!topic LSN on Compiler control via Pragmas !key LSN-1065 on Compiler control via Pragmas !reference MS-K;4.6 !from John McHugh $Date: 92/12/29 18:20:21 $ $Revision: 1.1 $ !discussion LSN on Compiler control via Pragmas John McHugh Co-author Safety and Security Annex 21 Dec 1992 INTRODUCTION: At the Salem WG-9 meeting, it was suggested that Compiler and Implementation behavior might be controlled by a series of restriction pragmas. This form of control would supplement, or possibly replace to some extent, the Safety and Security Annexes requirement for documentation of compilation and implementation behaviors. The WG-9 resolutions in question are: 5-2. Determinism: Pragmas to increase implementation determinism should be provided in the SC annex. 5-3. Restricted use of language features: There should be a pragma in the core language and a list of values in the Safety Critical and Security Annex which serve to restrict the use of language features. The language of the September Version of the Annex that is relevant to these resolutions states, in part: 2.5 Reviewable object code An implementation will provide a mode of operation in which the object code generated by the compiler is available in a manner which allows independent validation and verification. Specifically, this mode of operation will provide: 1. the order of elaboration of library units; 2. the mechanism used for passing of each parameter for which the language does not require a particular mechanism; 3. the method used for the allocation and deallocation of storage; 4. the method used to evaluate numeric expressions if this involves an extended range or extra precision; 5. a method of obtaining the object code generated in machine-readable format (for subsequent analysis by other tools); 8. code sequences derived entirely from one Ada statement must be indicated as such; 9. an indication of an Ada statement which results in no object code; 10. a method of determining which exception can be raised by any statement, and the location of the corresponding exception handler; This note is intended to provide a basis for further discussion of these issues. DETERMINISM: Resolution 5-2 calls for pragmas to increase implementation determinism as a part of the SC annex. This issue is addressed in part in section 2.5 of the current annex which calls for a conforming implementation to produce object code that can be clearly and easily related to the Ada source from which it was compiled. The current approach places only indirect restrictions on the implementation, leaving it up to the vendor to determine an appropriate tradeoff between restriction and documentation. It should also be noted that the issue of allowable execution orderings for the core of the Ada 9X language is still under discussion, awaiting the SEI study on optimization and code generation. For the purposes of this discussion, we assume that the determinism in question arises from choices made at compile time (or more rarely at run time) concerning issues for which the LRM contains the words "in some order that is not defined by the language" or their equivalent. It is usually the case that a given program compiled with a given compiler will behave in a deterministic fashion, consistent with the choices made by the compiler, but that these choices are not visible to the programmer. The issue of control can be addressed in several ways. The simplest, in terms of user expectations, but the most draconean in terms of its impact on implementations is to define a single, canonical, execution order and introduce a pragma that forces the implementation to adhere strictly to that order. Finer granularities are possible. Forcing the compiler to honor statement boundaries, evaluate actual parameters in a given order, use a particular parameter passing mechanism, etc. are also options. The examples that follow are not intended to be exhaustive, but are typical of the kinds of restrictions that might be imposed. We will assume for the sake of argument that PRAGMA RESTRICT has been defined and that the examples given below are possible subarguments to the argument ORDER of PRAGMA RESTRICT, e.g. The first example would be expressed as "PRAGMA RESTRICT (ORDER = CANONICAL);" Other forms such as a distinct PRAGMA ORDER( ... ) are also possible. ORDER DISCUSSION CANONICAL Code must be generated that executes in a strictly deterministic canonical order that is defined by imposing a choice for every case in which the normal language implementation is given a choice. STATEMENT Statements must be executed in a predefined order, but code may be reordered within a statement. All the code resulting from one Ada statement must be completed before any code from the succeeding statement is begun. SEQUENTIAL Parallel execution is not permitted. This prevents, for example, overlapping coprocessor and main processor execution and precludes the use of multiscalar architectures. PARAMETER Parameters must be evaluated in a predefined order, e.g. left to right. BY_VALUE Parameters for which there is a choice of passing mechanism must be passed by value. Note: This is not an order issue, strictly speaking, but it is a case in which the behavior of the program may be affected by the implementation choice. It could just as easily be expressed as a restriction. BY_REFERENCE Parameters for which there is a choice of passing mechanism must be passed by reference. Note: See previous note. This list is not intended to be exhaustive. If this approach is adopted, consideration (but not necessarily action) should be given to providing a control mechanism for each non-deterministic implementation choice in the Ada 9X language. RESTRICTION: Restrictions are a related issue and are the subject of resolution 5-3. The effect of a restriction pragma is to create a dialect of Ada in which certain language features may not appear as well as to constrain certain implementation strategies that may or may not be exclusively related to the use of particular language constructs. As an example of the latter situation, it is noted that many implementations use heap storage for entities other than those whose allocation is explicitly controlled by the program. Faced with an instance of PRAGMA RESTRICT (NO_HEAP), an implementation would be forbidden to use heap storage for any purpose and would have to reject a program that required its use. Restrictions serve at least three distinct purposes. The first is declarative and serves to notify the compiler that the occurrence of otherwise legal constructs in a program is to be treated as an error. Thus, a program containing an allocator is becomes illegal under the NO_HEAP restriction. The second is to restrict the behavior of the program, by, for example, forcing the compiler to emit code that it might otherwise suppress or optimize away. As an example, the NO_SUPPRESS restriction would not only render a program illegal if it contained PRAGMA SUPPRESS, but it would also prevent the implementation from suppressing constraint or range checks even if the compiler determined them to be unnecessary. The third is to permit a reduced run time system. Programs that contain a NO_TASKING restriction do not need to have tasking support in their run time system. The list of possible restrictive pragmas is open ended. The restrictions that follow are to be taken as examples. RESTRICTION DISCUSSION NO_HEAP Programs that explicitly allocate heap storage are illegal. Programs that implicitly use the heap in a given implementation must be rejected. Run time systems that do not support heap allocation may be constructed in conformance with this restriction. NO_TASKING Programs that explicitly contain tasking constructs are illegal. Run time systems that do not support tasking may be constructed in conformance with this restriction. NO_PRS As above but for protected records. NO_INTERRUPTS Programs that explicitly handle interrupts are illegal. Programs that implicitly require interrupt handling must be rejected. Run time systems that do not support interrupt handling may be constructed in conformance with this restriction. NO_REAL Programs that explicitly use REAL types are illegal. Programs that implicitly require real or floating point computations must be rejected. Run time systems that do not support real or floating point operations may be constructed in conformance with this restriction. NO_SUPPRESS Programs containing PRAGMA SUPPRESS are illegal. Implementations must make explicit exception checks wherever the language indicates that there is a possibility of a predefined exception being implicitly raised. NO_TEXT_IO Programs relying explicitly on the standard package Text_IO are illegal. Programs that implicitly require this package, i.e. through the inclusion of other implementation defined packages, must be rejected. Run time support for the Text_IO package need not be supplied. Note: Similar restrictions may apply to other predefined IO packages such as Sequential_IO, Direct_IO, etc. NO_OPTIMIZE This restriction prevents compiler optimization. It is equivalent to the order constraint CANONICAL combined with the NO_SUPPRESS restriction. NO_SIDE_EFFECTS Expressions are forbidden to have side effects. This means, among other things, that functions may not have OUT parameters and may not modify global objects either directly or through interaction with other subprograms. Other restrictions are clearly possible. It is probably possible to devise restrictions to enforce almost any arbitrary set of coding standards. Whether this should be done is the subject for considerable debate. DISCUSSION: Control over implementation details was one of the requirements that emerged from the Trusted Systems panel at the Destin, FL Ada 9X requirements workshop. It did not make it into the final requirements document. In a sense, control of implementations is the dual of the surviving requirement, the documentation of implementation choices which is the basis for section 2.5 of the existing annex. In the discussions that occurred during the requirements phase, the notion of control appeared to impose a substantial burden in implementors. For each ordering option or restriction, the implementor must, in effect, tune the compiler and run time system for a different language. Onerous though the documentation requirement may appear to be, it pales in comparison. >From the programmers viewpoint the ability to fine tune the language for a particular application domain, customer standards, and coding style is appealing. The idea that the implementation will diagnose lapses on the part of programmers raises the level of assurance that the system has been "done right." The question that must be answered by the community is the price. If implementors are unwilling or unable to provide the degree of control implied by the proposed restrictions, it is unlikely that implementations conforming to the annex will be available. This result would be self defeating. Discussion from both the implementor and user communities is needed. Potential users of the annex are invited to make a case for the benefits that would arise from the kinds of control proposed in this note and to suggest additional restrictions. Implementors are asked to provide inputs on their willingness and ability to support implementation of restrictions such as those proposed here as well as their ability and willingness to support the documentation requirements of the current annex.