OCP-results - Electrical and Computer Engineering

OCP Analysis and Adaptation Results
Rockwell Collins ATC
Iowa State University
May, 2003
Overview

Issues list

Pattern catalog

Tool support

OCP results

Plans
May 03
/ SLIDE 2
Issues list

Identifies 83 issues related to software for high assurance systems based on:
—
Handbook for Object-Oriented Technology in Aviation (OOTiA), Proceedings of
FAA/NASA Workshops 1 & 2 on Object-Oriented Technology in Aviation, 2003
—
Guide to the Certification of Systems with Embedded Object-Oriented Software,
Aerospace Vehicle Systems Institute (AVSI), 2001
—
Gary Daugherty, Certifiability of CORBA, Rockwell Collins Technical Report, 2001
—
“Object-Oriented Technology (OOT) In Civil Aviation Projects: Certification Concerns”,
CAST-4, January 2000, http://av-info.faa.gov/software
—
Leanna K. Rierson. Object-Oriented Technology (OOT) in Civil Aviation Projects:
Certification Concerns, Federal Aviation Administration, Washington, D.C.
—
Ye Wu and Jeff Offutt. Maintaining Evolving Component-Based Software with UML,
George Mason University Technical Report, 2002
—
Barbara Liskov and Jeanette Wing. “A Behavioral Notion of Subtyping”, ACM
Transactions on Programming Languages and Systems, 16(6): 1811-1841, November
1994.
May 03
/ SLIDE 3
Issues list

Includes both design level and language level issues:
—
Bertrand Meyer. “Applying design by contract.” IEEE Computer 25(10):40-51, October
1992.
—
Guide to the use of the Ada Programming Language in high integrity systems, ISO/IEC
TR 15942, 2000
—
John Barnes. High Integrity Ada: The SPARK Approach, Addison-Wesley, Harlow,
England, ISBN 0-201-17517-7, 1997
—
Use of the C++ Programming Language, Certification Authorities Software Team
(CAST), position paper, CAST-8, January, 2002
—
David W. Binkley. C++ in Safety Critical Systems, NIST, November 1995
—
Boeing, BCA Technical Standard for the Use of C++ in Airborne Software, D6-82801,
2002
—
Scott Meyers. Effective C++, 2nd edition, Addison-Wesley, Reading, MA, 1998
—
Scott Meyers. More Effective C++, Addison-Wesley, Reading, MA, 1996
—
Ian Joyner. C++??: A critique of C++ and Programming Language Trends of the 1990s,
1996
—
Marshall P. Cline and Greg A. Lamow. C++ FAQs, Addison-Wesley, Reading, MA,
1995.
May 03
/ SLIDE 4
Issues list

And issues related to verification and testing:
—
Jeff Offutt, et al. A Fault Model for Subtype Inheritance and Polymorphism, Twelfth
IEEE International Symposium on Software Reliability Engineering (ISSEE ’01), 2001
—
Robert T. Alexander et al. Fault Detection Capabilities of Coupling-based OO Testing,
Colorado State University Technical Report, 2001
—
Robert V. Binder. Testing Object-Oriented Systems: Models, Patterns, and Tools,
Addison-Wesley, Reading, MA, 2000.
—
Robert T. Alexander and Jeff Offutt. Analysis Techniques for Testing Polymorphic
Relationships, In Thirteenth International Conference on Technology of Object-Oriented
Languages and Systems (TOOLS30), 1999.
May 03
/ SLIDE 5
Pattern catalog

Forty two design patterns intended to address the most significant issues

Ten of these are abstract (define the problem)

Thirty two are concrete (provide specific/alternative solutions)

Specified in “Gang of Four” format

With formal specifications (to support automation) in XPSL/XML

And well defined relationships between patterns (extends, requires, excludes,
etc.)

Developed incrementally
May 03
/ SLIDE 6
Pattern catalog

Increment one
—
Development of eXtensible Pattern Specification Language (XPSL/XML)
—
Development of patterns for:
Control flow,
Data integrity,
Pointer integrity,
Unintended side effects,
Multiple inheritance
May 03
/ SLIDE 7
Pattern catalog

Increment two
—
Extension of XPSL (in terms of specific queries/views/transformations)
—
Development of patterns for:
Contracts and subtyping,
Coupling and cohesion,
OO metrics,
Dynamic resource allocation,
Safety critical language subsets
May 03
/ SLIDE 8
Tool support

For 8 patterns addressing 10 issues

Implementation based on ISU’s KCS toolset

Programs represented in eXtensible Common Intermediate Language (XCIL/XML)

Framework to support XPSL queries, views and transformations

Developed incrementally
May 03
/ SLIDE 9
Tool support

Increment one
—
Development of XCIL
—
Translation of C++ to XCIL,
—
Verification of translation,
—
Analysis framework (queries and views),
—
Analysis support for selected increment one patterns,
—
Focus on “local” patterns, affecting individual OCP components
May 03
/ SLIDE 10
Tool support

Increment two
—
Adaptation framework (transformations),
—
Adaptation support for selected increment one patterns,
—
Analysis support for selected increment two patterns,
—
Focus on “global” patterns, requiring an analysis of the entire OCP
May 03
/ SLIDE 11
Technical issues

Size of the OCP

Manual nature of the review process

Lack of tool support for HA analysis and transformation

Lack of user control (user defined patterns)

Regression testing (first do no harm)

Need to integrate with other tools
May 03
/ SLIDE 12
Technical Approach
Modeling tools
(GME, Rose, etc.)
HA
Models
Models
XML/XMI models
KCS
toolset
SW
(for translation,
analysis, and
adaptation)
Adapted XML/XMI models
HA
SW
Adapted OCP, and other software
source (in C++, Java, other languages.)
OCP and other software source
(in C++, Java, other languages)
Patterns in XML/XMI
Issues List
Catalog
Developer
of patterns for high
assurance software
Review/edit
T-VEC
formal
specs
T-VEC
Regression testing
May 03
/ SLIDE 13
OCP results

OCP 2.2

http://dirac.ee.iastate.edu/ocp/

Issues

Patterns

Matches

Adaptations
May 03
/ SLIDE 14
Classification of problems

Hard run time error
—

Lurking run time error
—

A problem that may fall into one of the run time error categories – although we don’t
know which.
Obstacle to analysis
—

A hard run time error may result if additional correct code is introduced.
Potential run time error
—

An error appears in the current code. A fault may occur when the erroneous code is
executed.
The code cannot be analyzed in some manner typically required for “certification”
(potentially masking/hiding run time errors).
Maintenance risk
—
The code is correct, but subsequent changes are likely to introduce errors.
May 03
/ SLIDE 15
Increment one

Addresses issues related to
—
Implicit type conversion
—
Violations of strong typing
—
Control flow
—
Compiler generated constructors, operators
—
Pointer integrity
May 03
/ SLIDE 16
Issue 4: Implicit type conversion

Implicit type conversion may involve a potential loss of data or precision
—
“Type conversions shall not be made from a longer to a shorter (number of bits) type”
“Type conversion shall not be made from an unsigned type to a signed type of the
same size”
“Type casting shall be explicitly coded with use of the keywords const_cast, static_cast
and reinterpret cast, and shall not be left as an operation only implied by the code (e.g.,
an assignment statement)”
Boeing. BCA Technical Standard for the Use of C++ in Airborne Software, D6-82801
—
“Loss of information rule. To help ensure correctness, any conversions that may result
in loss of data or data accuracy and precision should be explicit, should be
conspicuously marked (identified) in the program source code, and should only be
permitted after thorough review and analysis of potential adverse effects.” [OOTiA
Position Paper on Type Conversion]
May 03
/ SLIDE 17
Issue 4: Implicit type conversion

Implicit type conversion between logically unrelated types (e.g., integer and
boolean, character and integer) may violate the principles of strong typing
—
“Unchecked conversion rule. To help ensure type safety and verification, all unchecked
conversions should be explicit, be conspicuously marked (identified) in the program
source code, and be permitted only after thorough review and analysis of potential
adverse effects.” [OOTiA Position Paper on Type Conversion]
—
“Scalar type rule. Implicit conversions between scalar types should only be permitted
when the new type defines a set of operations that is logically a subset of those defined
by the old type.” [OOTiA Position Paper on Type Conversion]
—
“Supertype rule. To help ensure type safety and verification, all implicit type conversions
involving references to class instances should only represent a conversion from a
subtype to one of its supertypes.” [OOTiA Position Paper on Type Conversion]
May 03
/ SLIDE 18
Issue 4: Implicit type conversion

Implicit type conversion may incur a significant, hidden overhead (e.g., due to
implicit constructor calls)
—

“Low overhead rule. To ensure that the developer does not introduce significant hidden
overhead and performance issues, implicit type conversions should only be used for
predefined scalar types and references to structured types.” [OOTiA Position Paper on
Type Conversion]
Very hot to Hot, rank = 3
May 03
/ SLIDE 19
Pattern: Safe Type Conversion

Restricts implicit conversions to those that are type safe, low overhead, and
guarantee no loss of data or precision, i.e.
—
Conversion of a smaller integer type to larger integer type whose range subsumes the
original, with sign extension of two’s complement values
—
Conversion from a smaller IEEE 754 floating point type to a larger IEEE 754 floating
point type
—
Conversion from a reference type S to a reference type T, provided S is a subtype
(subclass or subinterface) of T
—
Conversion from an Array/Vector whose element type is a reference type SC to an
Array/Vector whose element type is a reference type TC, provided that SC is a subtype
of TC
—
Conversion from a general collection type whose element type is a reference type to a
collection of the same type whose element type is a reference type TC, provided that
SC is a subtype of TC
May 03
/ SLIDE 20
Pattern: Safe Type Conversion

Specifies that type conversions between logically unrelated types (e.g., integer
and boolean, character and integer) must be explicit

Specifies that type conversions that may incur a significant overhead (e.g., that
use constructors or conversion operators to perform type conversion) must be
explicit

Specifies that supertype to subtype conversions (down casts) must either be
proven to be correct (by means of analysis) or must be guarded by a run time
check
May 03
/ SLIDE 21
Matches

No implicit conversions between integer and float

58,675 implicit conversions of a larger value to a smaller value

352 implicit conversions of a signed value to an unsigned value

87 implicit conversions of an unsigned value to a signed value

Matches represent potential run time errors
May 03
/ SLIDE 22
Adaptations

Subject to review

Need to consider which implicit conversions are “high overhead”

Need report on types converted from/to

Need report on all writes to variables involved in conversions

Need to consider whether the actual range of values of the source type fits
within the range of values permitted by the destination type

Need to consider whether the converted values are treated as numeric values
(whether signed/unsigned matters)

Introduce user defined types or typedefs

Use bool instead of integer type

Use single size, avoid conversions

Use explicit conversions

Introduce run-time range checks (when not performed by C++)
May 03
/ SLIDE 23
To do

Identify “low overhead” vs. ”high overhead” implicit conversions

Provide the suggested reports as an aid to the review process

Provide for feedback (annotations) to feed the toolset information derived from
reviews

Look for all conversions between logically unrelated types (not just
integer/float)

Look for explicit conversions that involve a potential loss of data or precision

Look for down casts (supertype to subtype conversions)

Look for definitions of implicit conversion operations

See pattern for details
May 03
/ SLIDE 24
Issue 17: Break in switch

Error prone, especially when cases are later added or removed
—
“Each case in a switch, which contains any executable code, shall be terminated with a
break.”
“This eliminates the dubious practice of falling through a case to use code in a
succeeding case for common processing. It is too easy to lose track of the correct
program flow in code maintenance.”
Mandatory for DO-178B software levels A through D
Boeing. BCA Technical Standard for the Use of C++ in Airborne Software, D6-82801

Hot, Rank = 4
May 03
/ SLIDE 25
Pattern: Fall through switch case

Multiple cases may be associated with the same code

However, each block of code associated with a case must end in a ‘break’

This includes the last case of the switch statement (in case other cases are later
added after it)
May 03
/ SLIDE 26
Matches

461 fall through cases

Matches represent maintenance risks
May 03
/ SLIDE 27
Adaptations

Refactor code to either:
—
introduce a method called by both cases (when the shared code is cohesive)
—
introduce an inlined call (when the shared code is short and cohesive)
—
introduce a conditional (if statement or nested case) when the shared code is not
cohesive
—
introduce replicated code (when the shared code is short but not cohesive)
May 03
/ SLIDE 28
To do

Support one or more of the suggested adaptations

Support user selection of the adaptation to be applied
May 03
/ SLIDE 29
Issue 19: Use of goto’s

Complicates analysis
—

The use of goto should be excluded because it complicates flow analysis (FA),
symbolic analysis (SA), timing analysis (TA), and structural testing (ST).
The use of goto is regarded as both unnecessary, and undesirable compared to the
use of other control structures.
It should not appear in well written code.
Guide for the Use of the Ada Programming Language in High Integrity Systems,
ISO/IEC TR 15942
R. Chapman. SPARK – A state-of-the-practice approach to the Common Criteria
implementation requirements, Praxis Critical Systems
Hot, Rank = 4
May 03
/ SLIDE 30
Pattern: Goto-free execution


The pattern forbids all explicit goto’s
But does not forbid implicit goto’s (such as those implied by the use of if
statements, switch statements, loops, or exception throws)
May 03
/ SLIDE 31
Matches


1,744 explicit gotos
Matches represent false positives if the goto’s are generated by macros as a
substitute for exception throws (as many apparently are)

These should be OK, assuming exception handling/error handling jumps are
themselves allowed

Otherwise matches represent maintenance risks, obstacles to analysis, and
potential run time errors
May 03
/ SLIDE 32
Adaptations

Subject to review

Unless used as a substitute for exceptions, refactor code to:
—

replace goto with structured control flow (conditional, loop, break, continue, error return,
other common forms)
If used as a substitute for exceptions, apply exception/error handling patterns:
—
Enforcing the disciplined use of exceptions (per Bertrand Meyer)
—
Ensuring all reported errors (thrown exceptions) have handlers – as in Java
—
Eliminate macros in favor of pattern substitution, allowing a variety of error
reporting/error handling strategies
May 03
/ SLIDE 33
To do


Provide support to for “macro recognition”
Develop/apply error handling patterns, replacing the use of macros for this
purpose
May 03
/ SLIDE 34
Other related patterns from the catalog

Jump-free execution

No user thrown exceptions

Top level handler for predefined exceptions
May 03
/ SLIDE 35
Issue 25: Compiler generated operations


Compiler generated operations have default meanings that may be inappropriate
for a given class.
—
Since the default constructor, copy constructor, destructor, and the operators operator=,
operator&, and operator, (i.e., operator<comma>) all have default meanings; they
should be explicitly defined in every class. To avoid unwanted implicit calls to these
constructors and operators, declare them private. – [Binkley, C++ in Safety Critical
Systems]
—
Law of The Big Three: “If a class needs a destructor, or a copy constructor, or an
assignment operator, it needs them all” … “During code reviews and debugging
sessions, we have traced many core dumps back to violations of The Law” [Cline and
Lomow, C++ FAQs]
—
“Declare a copy constructor and an assignment operator for classes with dynamically
allocated memory” [Scott Meyers, Effective C++, 2nd edition, item 11]
—
Declare a constructor for all classes with an user defined invariant – Based on the
FAA/NASA OOTiA Handbook complete initialization rule, invariant rule and invariant
assertion rule
Hot, Rank = 4
May 03
/ SLIDE 36
Pattern: Compiler generated operations


Constructor rule
—
If we have a user defined invariant, we need a user defined constructor
—
All fields without initial values must be set by a user defined constructor
Copy constructor rule
—

Assignment rule
—

If the class has dynamically allocated components, we need a user defined assignment
operator
Destructor rule
—

If the class has dynamically allocated components, we need a user defined copy
constructor
If the class has dynamically allocated components, we need a user defined destructor
Consistency rule
—
If the class has a user overrides the default behavior of its destructor, copy constructor,
or assignment operator, then it should override the behavior of all three
May 03
/ SLIDE 37
Matches

1,451 classes with compiler generated default constructors

2,078 classes with compiler generated copy constructors

2,100 classes with compiler generated “=” operators

2,218 classes with compiler generated “&” operators

Matches are subject to application of the previous rules

Violations of the rules represent likely run time errors or lurking run time errors
May 03
/ SLIDE 38
Adaptations

The user is responsible for introducing the necessary operations, while the tool
is responsible for checking the user supplied code

In addition the tool may introduce run-times checks of constructor
postconditions, to ensure the class invariant is established

Checks of user supplied constructor


—
Run time check of invariant as postcondition
—
Check that all fields are initialized
Checks of user supplied copy constructor
—
Run time check of invariant as postcondition
—
Check that all dynamically allocated components are replicated (deep copy)
Check of user supplied assignment operator
—

Check that all dynamically allocated components are replicated (deep copy)
Check of user supplied destructor
—
Check that all dynamically allocated components are deallocated
May 03
/ SLIDE 39
To do

Provide tool support for associated rules

Support the selective insertion of code to check constructor postconditions
(class invariants)
May 03
/ SLIDE 40
Issue 30: Pointer arithmetic

Use of pointer arithmetic

Bounds checks and invalid pointer values
—
“Operational software shall not include pointer arithmetic.”
“In general, there is little justification for going to the effort of designing code to do
pointer arithmetic. The performance gained by doing pointer arithmetic is seldom worth
the increased risk of error.”
Explicit pointer value calculation is prohibited for DO-178B software levels A through D
Boeing. BCA Technical Standard for the Use of C++ in Airborne Software, D6-82801
—
“Direct manipulation of pointer values (pointer arithmetic) should be prohibited … Java
and C# can be used as a guide. What cannot be done is these languages generally
should not be allowed. ” [Daugherty, Certifiability of CORBA]

Obstacle to analysis

Hot, Rank = 5
May 03
/ SLIDE 41
Pattern: No pointer arithmetic

A pointer can be used only as a substitute for an opaque reference, i.e., in XCIL:
—
On the left hand side of an assignment
—
In a reference to the value of an attribute
—
In a reference to the value of an array element
—
In a reference to the length of an array
—
In reference to the run time type of an object
—
As the target of a dispatching call
—
As an argument to a call
—
As a value returned by a method
—
As the thrown value of an exception
—
In a reference to an object to be locked/unlocked
May 03
/ SLIDE 42
Matches

470 instances of pointer arithmetic

Matches represent potential run time errors and obstacles to analysis
May 03
/ SLIDE 43
Adaptations

Replace each array element pointer with an array base pointer and index,
performing all arithmetic on indices rather than pointer values

Selectively introduce run-time bounds checks (typically not performed by C++
compilers)

Restrict other uses of pointers in XCIL to the cases given (in which the use of a
pointer is compatible with the use of an opaque reference), requiring the user to
make associated changes
May 03
/ SLIDE 44
To do

Complete tools-related work on transformations to eliminate arithmetic
involving array pointers

Develop strategy for incremental introduction of changes
—
For examnple, support a conversion from array pointer types to a type representing
an array reference + index (class ArrayReference)
—
Explicitly apply this conversion to all parameters passed into/out of the portion of the
software to be changed
—
Incrementally adapt the entire OCP and its support libraries
May 03
/ SLIDE 45
Issue 47: Use of union (untagged variant records)

Can lead to errors that cannot be caught by the compiler and violations of
strong typing
—
“The type union should not be used”
“union is an untagged type. Its use can lead to data type errors that cannot be trapped
by the compiler”
Prohibited for DO-178B software levels A through D
Boeing. BCA Technical Standard for the Use of C++ in Airborne Software, D6-82801
—

“Use a class hierarchy with virtual functions in place of a union as it provides type
checking of the data stored in the union” [Binkley, C++ in Safety Critical Systems]
Hot, Rank = 6
May
17
April
03 /03
SLIDE
/ SLIDE
46
46
Pattern: Non-discriminated union

The pattern forbids all untagged (non-discriminated) unions
May 03
/ SLIDE 47
Matches

9 declarations of untagged union types

Matches represent maintenance risks, obstacles to analysis, and potential run
time errors
May 03
/ SLIDE 48
Adaptations

Replace untagged union with
—
class-subclass
—
class-state = tagged union (discriminated record)
May 03
/ SLIDE 49
To do

Add abstract pattern and two concrete subpatterns (for conversion to classsubclass and class-state) to catalog

Develop tool support for the associated transformations (giving the user a
choice of which to apply)
May 03
/ SLIDE 50
Issue 56: Implicit method return

Without an explicit return statement, the developer’s intent may be unclear,
control flow may be more difficult to follow, and it may be unclear what values
may be returned by a given method
—
“Return from a function shall be accomplished only by an explicit return statement, i.e.,
the code shall not use a default or implicit return.”
“Not writing return in a function relies on the default return. Explicit return in every
branch that terminates has two benefits. It simplifies the maintenance task of
understanding the flow of control, and makes it completely clear the possible values
that are returned.”
Mandatory for DO-178B software levels A through D
Boeing. BCA Technical Standard for the Use of C++ in Airborne Software, D6-82801

Other, Rank = 9
May 03
/ SLIDE 51
Pattern: No implicit method value return

All execution paths associated with a method that returns a value must end with
an explicit return
May 03
/ SLIDE 52
Matches

None found
May 03
/ SLIDE 53
Unimplemented local patterns

Enforce invariant (Issue 13)

Closed argument list (Issue 15)

No dangling pointers to local variables

No assignment statement arguments (Issue 40)

Loop termination (Issue 44)

No user thrown exceptions (Issue 49)

Top level handler for predefined exceptions (Issue 49)
May 03
/ SLIDE 54
Unspecified local patterns

Undefined and implementation defined behavior (Issue 2)

Incomplete construction (Issue 12)

Use/overriding of default parameter values (Issue 16)

Accidental mismatch of software and processor (or compiler), e.g. with respect
to desired precision and accuracy (Issue 27)

Overloading and implicit type conversion involving calls to overloaded methods
(Issue 28)

Side effects in expressions and arguments (Issue 50)

Side effects in functions that return a result (other than an error code) (Issue 51)

Template verification (Issue 52)

Verification of inlined methods (Issue 53)

Class cohesion (Issue 66)
May 03
/ SLIDE 55
Increment two

Addresses issues related to
—
Lack of precise requirements/interface specifications
—
Integration errors at class boundaries
—
Supertype/subtype compatibility
—
Use of dynamic dispatch
—
Dynamic dispatch during object construction
—
Safety critical language subsets
May 03
/ SLIDE 56
Issue 1: Precise requirements/interface specifications


Lack of precise requirements/interface specifications
—
“If we don’t state what a module should do, there is little likelihood that it will do it (The
law of excluded miracles)” – Bertrand Meyer
—
Programming by contract: “The relationship between a class and its clients [can be]
viewed as a formal agreement [contract]. Only through such a precise definition of
every module’s claims and responsibilities can we hope to attain a significant degree of
trust in large software systems” [Bertrand Meyer, Object-oriented Software
Construction]
Integration errors at class interface boundaries
—
—

“The compositional relationships of inheritance and aggregation, especially when
combined with polymorphism, introduce new kinds of integration faults” and “increase
the difficulty of the detection of faults that result from the integration of components” –
Roger T. Alexander
In OO systems, “complexity is relocated to the connections among components” and
“there is less static determinism (many faults can now only be detected at runtime)” Offutt
Very hot, Rank = 1
May 03
/ SLIDE 57
Issue 6: Supertype/subtype compatibility


“The single largest source of design errors is improper inheritance” [C++ FAQs,
Issue 119]
Faulty intuition
—

Intuition with regard to classification can lead to superclass-subclass relationships that
violate the Liskov Substitution Principle (a.k.a. “Square peg in a round hole”) [Binder,
Testing Object-Oriented Systems]
Failure to implement to inherited specifications
—
A subclass may fail to follow the Liskov substitution principle, breaking the promises to
clients made by superclasses (a.k.a. “Naughty children”) [Binder, Testing ObjectOriented Systems, p. 503]
—
Subclass methods may fail to act on superclass attributes that are modified by methods
they override (a.k.a. “State Definition Anomaly (SDA)”) or may assign them inconsistent
values (a.k.a. “State Defined Incorrectly (SDI)”) – Offutt
—
A method may call other overridden (possibly private or protected) methods that break
the promises made by their parent methods (a.k.a. “Indirect Inconsistent State Definition
(IISD)” or “State Visibility Anomaly (SVA)”) - Offutt
May 03
/ SLIDE 58
Issue 6: Supertype/subtype compatibility


Failure to implement to inherited specifications
—
“Revoking an inherited public service is evil” [C++ FAQs, Issue 122]
—
“It’s legal for an overridden method to do nothing if, and only if, the specification of the
service in the base class tells users that it might do nothing. Without such an adaptable
specification in the base class, doing nothing is like false advertising.” [C++ FAQs, Issue
127]
Misuse of inheritance to share code/data
—

Inheritance can be misused to support code sharing without consideration of
substitutability and the rules for behavioral subtyping (i.e., LSP)
Programmer specified optimizations
—
Some languages make it easy to break the inheritance and subtyping guidelines in
order to perform programmer specified optimizations (e.g., by omitting the C++ “virtual”
keyword to avoid the overhead of dynamic dispatch).
May 03
/ SLIDE 59
Issue 6: Supertype/subtype compatibility



Accidental overriding/hiding
—
It is important that the overriding of one operation by another always be intentional rather
than accidental (a.k.a. “Accidental override”) [Binder, Testing Object-Oriented Systems]
—
The overriding of an attribute in a subclass can hide a superclass attribute with the same
name resulting in an inconsistent state when a sequence of superclass and subclass
methods are called (a.k.a. “State Definition Inconsistency (SDIH)”) - Offutt
Missing override
—
Failure to override a method, e.g., in order to maintain a stronger subclass invariant, will
not be detected by compilers, leading to undetected errors (a.k.a. “Missing override”)
[Binder, Testing Object-Oriented Systems, p. 502]
—
As a result, superclass methods may put a subclass in a state inconsistent with the
subclass invariant (a.k.a. “Inconsistent Type Use (ITU)”) – Offutt
Hot, Rank = 4
May 03
/ SLIDE 60
Issue 23: Use of dynamic dispatch


Dynamic dispatch raises potential issues with respect to flow analysis, timing
analysis, structural coverage, and the reuse of test results
—
“Data flow analysis and control flow analysis are complicated by dynamic dispatch,
because it may be unclear which method in the inheritance hierarchy is going to be
called.” [FAA/NASA Handbook for Object-Oriented Technology in Aviation (OOTiA)]
—
“Structural coverage analysis is complicated by dynamic dispatch because structural
coverage changes when going from subclass to superclass. A closely related issue is
that inheritance and polymorphism may cause difficulty in obtaining structural coverage
(both modified condition/decision coverage (MC/DC) and decision coverage). ”
[FAA/NASA Handbook for Object-Oriented Technology in Aviation (OOTiA)]
—
“Requirements-based testing is complicated by dynamic dispatch, because it may be
difficult to determine how much superclass verification activity can be reused for its
subclasses.” [FAA/NASA Handbook for Object-Oriented Technology in Aviation
(OOTiA)]
Hot, Rank = 4
May 03
/ SLIDE 61
Issue 5: Dynamic dispatch during object construction


Need to ensure subclass methods are not called before subclass data has been
initialized, establishing the subclass invariant
—
“Dynamic dispatch can introduce problems related to initialization (i.e., especially with
regard to deep class hierarchies)” [Binder]
—
Use of dynamic dispatch by a superclass constructor (or by a method in the transitive
closure of this constructor) can lead to the use of subclass attributes before they have
been initialized (a.k.a. “Anomalous Construction Behavior (ACB1)”) - Offutt
—
Use of dynamic dispatch by a superclass constructor (or by a method in the transitive
closure of this constructor) can lead to the use of superclass attributes before they
have been initialized (a.k.a. “Anomalous Construction Behavior (ACB2)”) - Offutt
Hot, Rank = 4
May 03
/ SLIDE 62
Pattern: Formal interfaces


Addresses Issue 1: Lack of precise requirements/interface specifications
—
“If we don’t state what a module should do, there is little likelihood that it will do it
(The law of excluded miracles)” – Bertrand Meyer
—
Programming by contract: “The relationship between a class and its clients [can be]
viewed as a formal agreement [contract]. Only through such a precise definition of
every module’s claims and responsibilities can we hope to attain a significant degree
of trust in large software systems” [Bertrand Meyer, Object-oriented Software
Construction]
—
MC/DC test coverage criteria [DO-178B]
Matches
—
All class interfaces

See SEC Catalog for details

Use of Daikon tool from MIT [Ernst] may allow pre/postconditions to be generated
semi-automatically from code
May 03
/ SLIDE 63
To do

Initially formal interfaces will be developed in terms of T-VEC
pre/postconditions with no support from the KCS toolset

Subsequently pre/post specifications will be imported/exported by the KCS
toolset in order to:
—
Support the checks specified by the Formal Interface pattern
—
Permit the selective use of pre/post and invariant specifications as the basis for the
generation of run-time checks (as in Eiffel)
—
Support the types of analysis/adaptation suggested by the Formal Subtyping pattern

Initially this will involve a conversion to/from the T-VEC file format

Eventually it should be possible to import/export this information from UML
requirements and design models

And to provide assistance to the user in the generation of formal
specifications from existing code (e.g., using Daikon or similar tools)
May 03
/ SLIDE 64
The importing of T-VEC pre/post specifications
Extended UML
UML
XMI
XCIL
map/
merge
Action Semantics
JVM
MS-IL
XCIL (1.3g)
C++ (EDG AST)
XCIL
map
T-VEC specs
XCIL
map/
merge
May
20
Mar
03 03
/ SLIDE
/ SLIDE
6565
The exporting of pre/post specifications to T-VEC
Extended UML
UML
XMI
XCIL
extract/
map
Action Semantics
JVM
MS-IL
XCIL (1.3g)
C++ source line mapping
XCIL
map
T-VEC specs
XCIL
extract/
map
May
20
Mar
03 03
/ SLIDE
/ SLIDE
6666
Pattern: Inheritance with overriding

Simple overriding rule

Accidental override rule

Simple dispatch rule

Complete initialization rule

Initialization dispatch rule
May 03
/ SLIDE 67
Pattern: Method extension

Method extension rule

Sole exception to the simple dispatch rule imposed by the Inheritance with
overriding pattern

See SEC Catalog for details
May 03
/ SLIDE 68
Patterns: Formal subtyping

Addresses
—
Issue 6: Supertype/subtype compatibility
—
Issue 23: Use of dynamic dispatch
Issue 5: Dynamic dispatch during object construction
—

In particular
—

“The single largest source of design errors is improper inheritance” [C++ FAQs, Issue
119]
Errors may result from
—
—
—
—
—
—
Faulty intuition
Failure to implement to inherited specifications
Misuse of inheritance to share code/data
Programmer specified optimizations
Accidental overriding/hiding
Missing override
May 03
/ SLIDE 69
Pattern: Formal subtyping


Analysis results
—
938 subtyping relationships
—
1,392 cases in which an operation is implemented by multiple methods (OMM pointcut)
—
3,112 instances of “true dynamic dispatch” (TDD pointcut)
—
Interested in subsets (OMM incompatibilities) and intersections (OMM incompatibilities
with TDD) to separate hard run-time errors from lurking errors
Review results (sample of ~40 subtyping relationships)
—
24 violations of subtyping rules/LSP (including conflicting postconditions, less visible
subclass operations, disabled methods, null method implementations, and weaker
postconditions)

Violations represent either lurking or hard run time errors

See SEC Catalog and OCP Subtyping Relationships for details/adaptations
May 03
/ SLIDE 70
Matches

938 subtyping relationships

1,392 instances of operations implemented by more than one method (OMM)

3,112 instances of true dynamic dispatch (TDD)
May 03
/ SLIDE 71
OMM checks

Check OMM for violations of LSP
—
Tool can identify all instances of OMM
—
Violations of LSP are associated with relationships (between an operation and an
implementing method, or between a method and an overriding method)
—
Tools can identify certain simple violations
—
Others can be found in manual reviews
MethodA1
Relationships between overriding
methods must comply with LSP, or
be marked as an error
OperationA
Relationships between the
operation and its implementing
methods must comply with
LSP, or be marked as an error

MethodA2
MethodA3
Represents either a hard run time error or a lurking error
May 03
/ SLIDE 72
TDD checks

Problematic call occurs when LSP violation in TDD operation-method set
—
Considering only the operation and the methods that could be invoked as a result of the
call (i.e., those defined by subtypes of the declared type of the target object)
—
There is an LSP violation in this set (between the operation and one of the methods, or
between a method and an overriding method)
Call to
target.operationA ()
OperationA
MethodA2
The call is OK as long as all
these relationships comply
with LSP
MethodA3

Represents a hard run time error if the client depends on the erroneous
relationship

Or a lurking error otherwise
May 03
/ SLIDE 73
Review results


24 violations of subtyping rules/LSP found in a manual review of a sample of
~40 subtyping relationships, including:
—
conflicting postconditions (CPOST),
—
less visible subclass operations (LVO),
—
disabled methods (DISM),
—
null method implementations (NMI),
—
weaker postconditions (WPOST)
See the OCP Subtyping Relationships report for further details
May 03
/ SLIDE 74
To do

Include checks for the most common LSP and specification errors that can be
found by tools (LVO, DISM, INVI, NMI, UNERR, OVER, UNDER)

Allow user specification of additional LSP violations (CPOST, INVI, MINV, OVER,
UNDER, WPOST, etc.) detected in reviews

Have the toolset track which LSP relationships have not been checked (all OMM
relationships should be reviewed)

Determine which instances of TDD represent “problematic” calls

Introduce related transformations (as suggested in the slides that follow)

Provide tool support for checking the simple dispatch rule (Inheritance with
overriding pattern) and the method extension rule (Method extension pattern)

Extend tool support to include all pointcuts, views, and transformations defined
by the Formal Subtyping pattern and the “inheritance” of pre/postconditions
May 03
/ SLIDE 75
Less visible operation (LVO)

An inherited operation is made less visible in a subclass

Revoking an inherited public service is evil” [C++ FAQs, Issue 122]

And a fundamental violation of LSP

And a violation of the rules defined by the Inheritance with overriding pattern

Easily detectable by toolset

One instance found in manual review of ~40 OCP subclasses

Can refactor the class to introduce a precondition and query to make the
operation optional

Or refactor the class hierarchy
May 03
/ SLIDE 76
Unexpected error (UNERR)

An overriding operation/method reports an error not specified in its
supertype/superclass

A fundamental violation of LSP

And a violation of the rules defined by the Inheritance with overriding pattern

Potentially detectable by toolset, given a formally stated postcondition

Two instances found in manual review of ~40 OCP subclasses (one representing
DISM)

Can respecify parent operation to allow reporting of the error

Or treat it as a case of NMI if the error corresponds to this
May 03
/ SLIDE 77
Disabled method (DISM)

An existing method is overridden in a subclass by method that asserts that the
method is disabled

A special case of UNERR and a fundamental violation of LSP

And a violation of the rules defined by the Formal subtyping pattern

Detectable by toolset, given the possible forms a disabled method may take

One instance found in manual review of ~40 OCP subclasses

Can refactor the class to introduce a precondition and query to make the
operation optional

Or refactor the class hierarchy
May 03
/ SLIDE 78
Invalid or incomplete implementation (INVI)

The execution of the method does not deliver on the promises made by the
operation/method’s description/postcondition (whether inherited or defined by
the class)

A violation of LSP

And a violation of the rules defined by the Formal subtyping pattern

Most easily detected by review

But some cases can be caught by toolset given a formally stated postcondition

Or by looking at special cases (such as NMI)

14 instances found in manual review of ~40 OCP subclasses (12 of them
instances of NMI)
May 03
/ SLIDE 79
Null method implementation (NMI)

A method of a concrete class defines a null implementation of an operation that
conflicts with its description (whether inherited or defined by the class).

A special case of INVI, and a violation of [C++ FAQs, Issue 127].

“It’s legal for an overridden method to do nothing if, and only if, the
specification of the service in the base class tells users that it might do nothing.
Without such an adaptable specification in the base class, doing nothing is like
false advertising.” [C++ FAQs, Issue 127]

Detectable in most cases by toolset, given given the possible forms a null
method may take

12 instances found in manual review of ~40 OCP subclasses

Can specify a precondition to make the operation optional, or qualify the
postcondition to specify that the operation may do nothing

If all operations of the class are null, then it is preferable to address this as a
case of NSCI
May 03
/ SLIDE 80
Null subclass implementation (NSCI)

NMI for all methods of subclass

Suggested by NullObject pattern

Problematic in high assurance systems


—
Unless it is a null implementation is always OK, for all clients under all circumstances
—
And the class name/contract defined by the superclass makes this clear
Should be replaced by HA version of the pattern, which:
—
Ensures any optional null behavior is defined by each superclass operation’s pre/post
specification, i.e., the postcondition is of the form “true or optional-result”
—
Names the superclass to make it clear that it’s implementation may be null
—
Defines a subclass that represents the root of all non-null implementations (so that
clients that require a non-null implementation can use strong typing to guarantee this)
Or (less desirable) refactor the base class to introduce postconditions and the
query isNull to make all results explicitly optional
May 03
/ SLIDE 81
Null subclass implementation (NSCI)
For example, replace Lock, NullLock, LockImpA, LockImpB
Lock
NullLock
LockImpA
LockImpB
With OptionalLock, NullLock, Lock, LockImpA, LockImpB
postcondition indicates result is optional
OptionalLock
NullLock
postcondition indicates result is guaranteed
Lock
LockImpA
LockImpB
May 03
/ SLIDE 82
Null subclass implementation (NSCI)
Or (less desirable), refactor the Lock class to introduce postconditions and query
isNull to make all results explicitly optional
Refactor to introduce postconditions and
query isNull to make all results explicitly
optional
Lock
NullLock
isNull returns true
LockImpA
LockImpB
isNull returns falae
May 03
/ SLIDE 83
Overspecified operation (OVER)

An operation is overspecified by its description

Usually as a consequence of specifying implementation details rather than just
the result, from the client’s perspective

A violation of the OOTiA Coupling pattern

Can be detected by tools, given formally specified pre/postconditions

Neither the pre or post should contain references to features of the class that
are less visible than the operation being specified

One instance found in manual review of ~40 OCP subclasses
May 03
/ SLIDE 84
Underspecified operation (UNDER)

An operation is underspecified by its description, e.g., by failing to specify how
errors are reported (UNDER-ERR)

See the Formal interface pattern

Errors of omission are detectable by toolset, given a formally specified
postcondition

The tool can, for example, determine when a change to a public property of the
class fails to appear in the postcondition

7 instances found in manual review of ~40 OCP subclasses
May 03
/ SLIDE 85
Other violations of LSP

To detect other violations of LSP we can structure the pre/postconditions to
make the relationships between them obvious (as in Eiffel)

To ensure the precondition is weaker or the same in a redefined operation, for
instance, we can assume the parent precondition is “inherited”, and only allow
it to be extended by or’ing it with an additional clause

And to ensure the postcondition is stronger or the same in a redefined
operation, we can assume the parent postcondition is “inherited”, and only
allow it to be extended by and’ing it with an additional clause

Always specifying pre/postconditions in this way makes them easy to verify
(using tools such as T-VEC that generate test cases from pre/postconditions)

See the Formal subtyping pattern in SEC Catalog
May 03
/ SLIDE 86
Pattern: Subtyping tests generated from formal interfaces

Minimum compatibility rule

LSP compliance rule

Redefined/implementing precondition rule

Redefined/implementing postcondition rule

Subtype invariant rule

Inherited test case rule

Separate context rule
May 03
/ SLIDE 87
Pattern: Subtyping tests generated from formal interfaces

Assumes contracts can be written after the fact
—

“Contracts are inherent in library design; if not explicitly stated, they are lurking anyway
under the cover, either suppressed or replaced by comments in the program,
explanations in the documentation, exceptions and other ersatz techniques.” –
Bertrand Meyer
Assumes tool support for test case generation from pre/postconditions
—
Using T-VEC
May 03
/ SLIDE 88
To do

Generate T-VEC specs (by hand) for all modules we plan to change

Follow the Formal subtyping pattern with respect to the rules for the
“inheritance” of pre/postconditions and compliance with LSP

Introduce KCS tool support for the importing/exporting of T-VEC specs


Provide tool support for the “inheritance” of pre/postconditions in accordance
with the pattern
Explore the use of tools such as Daikon to generate pre/post specifications
from code
May 03
/ SLIDE 89
Pattern: Multiple implementation inheritance



Addresses issue 8: Ambiguity resulting from the use of multiple implementation
inheritance
Multiple inheritance session of OOTiA workshop unattended because no one
thought MII appropriate for high assurance applications
Review results (sample of ~40 subtyping relationships)
—
4 instances of multiple implementation inheritance

Matches represent maintenance risks and potential run time errors

Rules
—

Replace with delegation for DO-178B levels A through C
See SEC Catalog for details/adaptations
May 03
/ SLIDE 90
To do

Provide tool support for the identification of cases of multiple implementation
inheritance and the pointcuts associated with the pattern

Provide tool support for the replacement of multiple implementation
inheritance with delegation
May 03
/ SLIDE 91
Issue 71: Obstacles to level A static analysis

Need for level A static analysis, including data/control flow analysis

Need for formally defined semantics

Need for an analyzable, precisely defined language subset for safety-critical
applications

Hot, Rank = 4
May 03
/ SLIDE 92
Pattern: Safety critical formal language subset

Limit XCIL actions and predefined types to those that map to the UML Action
Semantics or the JVM

While permitting the use of structural elements from UML (classes, interfaces,
components, operations, methods, etc.) to organize them

Impose additional restrictions based on the ISO High Assurance Ada standard
and SPARK, including those defined by other patterns in the catalog

See the SEC Catalog for details
May 03
/ SLIDE 93
To do

Provide tool support to identify actions that do not map to the JVM instruction
set

Provide tool support for the identification of functions with side effects and
other restrictions mentioned by the pattern

Provide tool support for other SPARK-like patterns called for by this pattern
(which have not already been implemented)

Formally define this pattern in XPSL
May 03
/ SLIDE 94
Lessons learned

Tool support has been invaluable in identifying potential problems
—
—

More effective in terms of hours spent, accuracy, and counts of problems found
Necessary due to size of OCP
Need to be able to interactively refine problem description, tune patterns
May 03
/ SLIDE 95
Lessons learned



A broad, automated problem analysis is needed to find likely problems
—
Given size of the OCP
—
And number of issues
Results of analysis should dictate which patterns to develop further
—
Need to consider both ranking and probability of occurrence
—
Need to support interactive exploratory analysis
—
Need to refine problem analysis to include discriminators
Need to support a progression from manual, to interactive, to fully automated
transformation
—
Most important transformations require developer in the loop
—
Need to support use of tool as an assistant
—
Need to support critics/review process
May 03
/ SLIDE 96
Lessons learned

Need automated support for the evolution of meta-models (XCIL, XPSL)
—

Need automated checking of translation results
—



These change frequently
Well formedness rules
Need to support import/export from multiple tools (e.g., UML, C++, T-VEC)
—
Need to merge inputs from different tools into common XCIL model
—
Need to extract XCIL and map to multiple representations (XMI, T-VEC pre/post, C++)
Reliance on XML comes at a price
—
Supports rapid tool development
—
But need lots of processing power/space
—
Can optimize toolset itself (using patterns) after the fact
Target language independence works
May 03
/ SLIDE 97
Unimplemented global patterns

Synchronization (Issue 3)

Multiple interface inheritance (Issue 7)

Replacement of multiple implementation inheritance with delegation (Issue 8)

No dynamic allocation after initialization (Issue 9)

Initialization before use (Issue 12)

Class coupling (Issues 13, 67, 68)

Dynamic dispatch test coverage

Method extension

Deep hierarchy
May 03
/ SLIDE 98
Unspecified global patterns

Checking of inputs and outputs at partition boundaries (Issue 1)

Concurrency (Issue 3)

Aliasing, involving pointers or arguments (Issue 11)

Enforcement of safety invariants (Issue 14)

Re-entrant function execution (Issue 18)

Enforcement of architectural layering/partitioning rules (Issue 24)

Initialization dependencies between classes/modules (Issue 46)

Unreachable deactivated code (Issue 57)
May 03
/ SLIDE 99