Programming languages -- Ada
DEFECT REPORTS

Part 1
For ISO/IEC 8652:1995



September 2000



This document was prepared by AXE Consulting under contract from The MITRE Corporation.

© 2000, The MITRE Corporation. All Rights Reserved.

This document may be copied, in whole or in part, in any form or by any means, as is, or with alterations, provided that (1) alterations are clearly marked as alterations and (2) this copyright notice is included unmodified in any copy. Any other use or distribution of this document is prohibited without the prior express permission of MITRE.

You use this document on the condition that you indemnify and hold harmless MITRE, its Board of Trustees, officers, agents, and employees, from any and all liability or damages to yourself or your hardware or software, or third parties, including attorneys' fees, court costs, and other related costs and expenses, arising out of your use of this document irrespective of the cause of said liability.

MITRE MAKES THIS DOCUMENT AVAILABLE ON AN "AS IS" BASIS AND MAKES NO WARRANTY, EXPRESS OR IMPLIED, AS TO THE ACCURACY, CAPABILITY, EFFICIENCY MERCHANTABILITY, OR FUNCTIONING OF THIS DOCUMENT. IN NO EVENT WILL MITRE BE LIABLE FOR ANY GENERAL, CONSEQUENTIAL, INDIRECT, INCIDENTAL, EXEMPLARY, OR SPECIAL DAMAGES, EVEN IF MITRE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.

Introduction

This document contains defect reports on the Ada 95 standard [ISO/IEC 8652:1995], and responses formulated by the Ada Rapporteur Group (ARG) of ISO/IEC JTC 1/SC 22/WG 9, the Ada working group. The ARG is the language maintenance subgroup of WG 9, meaning that it is responsible for determining the corrections to the standard.

Defect Reports usually come from comments submitted by the public to the ARG. These comments are distilled into a question, given in the Question section of the Defect Report response.

In order to formulate the response to the Defect Report, the question is carefully considered and often discussed at length by the ARG. The results are recorded in the Discussion section of the response. The answer to the question arrived at after the discussions is summarized in the Summary of Response section. A more detailed answer to the question can be found in the Response section. Sometimes, the issue is so obvious that there is no Response or Discussion section. If the result of the discussion finds that some change to the standard would be required to arrive at an answer to the question, a Corrigendum Wording section includes the specific wording change to standard. These Corrigendum Wording sections are gathered together in a Technical Corrigendum document.

A Defect Report and Response is the final step of a lengthy process of formulation, discussion, and approval. The working documents of the ARG (called Ada Issues) contain additional information about the issue and its resolution. Ada Issues may include sections for testing information (ACATS test), informal wording changes (Wording), and an appendix including E-Mail comments on this issue (Appendix). These sections are not included in the Defect Reports found in this document. This information is available in the Ada Issues documents, which can be accessed on the web at www.ada-auth.org/~acats/arg.

The Defect Reports and Responses contain many references of the form ss.cc(pp) or ss.cc.aa(pp). These refer to particular paragraphs in the standard, with the notation referencing the (sub)clause number in the Ada 95 standard (ss.cc.aa), followed by a parenthesized paragraph number (pp). Paragraphs are numbered by counting from the top of the (sub)clause, ignoring headings.

The Defect Reports and Responses contain references to the Annotated Ada Reference Manual (AARM). This document contains all of the text in the Ada 95 standard along with various annotations. It was prepared by the Ada 95 design team, and is intended primarily for compiler writers, test writers, and the ARG. The annotations include rationale for some rules. The AARM is often used by the ARG to determine the intent of the language designers.

The Defect Reports and Responses may contain references to Ada 83. Ada 83 is the common name for the previous version of the Ada standard, ISO/IEC 8652:1987. Similarly, AI83 refers to interpretations of that standard.

This document contains all of the Defect Reports used to prepare Ada Technical Corrigendum 1. Issues which did not result in wording changes to the standard are available in the companion document, Defect Reports Part 2. Resolutions of newer issues can be found on the web site mentioned previously.

This document is designed to be viewed with the default font as some Roman font, similar to the Ada 95 standard. This may require some adjustments to your browser.




8652/0001 - The AE characters are allowed in identifiers

Working Reference Number AI95-00124
Report Qualifier -- Clarification Required
Section References
1.2

Question

2.1(8-9) say:

The letters allowed in identifiers are then restricted to lower_case_identifier_letters and upper_case_identifier_letters.

The version of 10646-1:1993 referred to in 1.2(8) names codes C6 and E6 as "Latin Capital Ligature AE" and "Latin Small Ligature AE".

This seems to imply that these characters are not allowed in identifiers. Are these characters allowed in identifiers? (Yes.)

Summary of Response

The characters LATIN CAPITAL LETTER AE and LATIN SMALL LETTER AE are allowed in identifiers.

Corrigendum Wording

Replace 1.2(8):

by:

Discussion

Technical Corrigendum 1 of 10646 names these characters LATIN CAPITAL LETTER AE and LATIN SMALL LETTER AE. The intent was that these letters be allowed in identifiers.




8652/0002 - Elaboration of subtype_indications with per-object constraints

Working Reference Number AI95-00171
Report Qualifier -- Omission
Section References
3.3.1; 3.6; 3.8; 4.8; 9.5.2

Question

When does the elaboration of a subtype indication with a per-object constraint occur? What are the actions of such an elaboration?

When a component has a subtype_indication with a per-object constraint and an object of the type containing the component is declared, the subtype_indication containing the per-object constraint is apparently never elaborated.

3.8(18) explains that subtype_indications with per-object constraints are not elaborated, but that any expressions that are not part of a per-object expression are evaluated. However, what to do with the results of those evaluations never seems to be explained.

3.3.1(15-20) describes the process of elaborating an object_declaration. In step 3, per-object expressions are evaluated, but there is no mention of elaborating anything, although later paragraph 20 does seem to imply that some sort of elaborations were supposed to have taken place in step 3.

The elaboration of per-object constraints is mentioned in (at least) the following other places where objects are created:

According to a strict reading, elaborating the per-object constraint would appear to involve reevaluating the non-per-object expressions (since there doesn't seem to be any separate definition of what happens when a per-object constraint is elaborated), but not include any subtype compatibility checks that would normally occur as part of subtype elaboration (since elaboration of the subtype_indication containing the constraint isn't mentioned in these paragraphs). What are the intended semantics?

Summary of Response

The elaboration of a subtype indication with a per-object constraint occurs when an object of the enclosing type is created. This elaboration consists of the evaluation of each per-object expression of the constraint, followed by the usual actions associated with such elaboration, but using the values for any expressions that are not part of a per-object expression that were determined earlier when the type definition was elaborated.

For evaluating a named association applying to multiple components in a per-object discriminant constraint, if the expression of the association is not part of a per-object expression, then it must be evaluated once for each associated component.

Corrigendum Wording

Replace 3.3.1(18):

by:

Replace 3.6(22):

by:

Replace 3.8(18):

by:

Replace 4.8(10):

by:

Replace 9.5.2(22):

by:

Response

Notwithstanding the rules given in 3.3.1(18), 4.3.1(19), and 4.8(10), the elaboration of the subtype indication of a component definition with a per-object constraint occurs when an object of the enclosing type is created. This elaboration takes place on elaboration of an object declaration, evaluation of an uninitialized allocator, and when evaluating an aggregate of the type.

The elaboration consists of the evaluation of each per-object expression of the component's constraint, followed by the conversion of the value of each expression of the constraint to its appropriate expected type and the performance of the compatibility check defined for the elaboration of the subtype indication (see 3.2.2(11)). The values used for any expressions that are not part of per-object expressions of the subtype's constraint are those determined during the original elaboration of the component definition as defined in 3.8(18). Such expressions are not reevaluated during elaboration of the per-object constraint that occurs as part of object creation, despite any rules that state when a per-object constraint is elaborated (e.g., as part of evaluating an allocator or aggregate).

Note further that the evaluation of expressions in a per-object constraint defined in 3.8(18) was intended to take into account the case of named associations for multiple components in a discriminant constraint. For such an association, the expression must be evaluated once for each associated component, as prescribed by 3.7.1(12).

Discussion

There are two basic problems with the current wording of the standard regarding the elaboration of components with a per-object constraint. The first is that the rules don't explain what is done with the values obtained from expressions that are not part of per-object expressions (as defined in 3.8(18)) or whether such expression are reevaluated when a per-object constraint is later elaborated during object creation. The other problem is that the mention of elaboration of per-object constraints in rules such as 4.3.1(19) and 4.8(10) fails to cover the need for the subtype compatibility check that is normally performed when elaborating a subtype indication.

The intent was clearly that the values of the expressions evaluated as part of elaborating a component definition with a per-object constraint (3.8(18)) should be used later when creating an object of the containing type. It would not make sense to discard the values already determined and to reevaluate the expressions (especially if they have side effects). The description in the rules for allocator and aggregate evaluation that states that a per-object constraint is elaborated should mention that only the per-object expressions are evaluated at that point and that the values for other expressions are those determined earlier when the type was elaborated. (The description of the semantics of elaborating per-object constraints should really be centralized in a single place, such as 3.8(18).)

The rules for object declarations, allocator evaluation, and aggregate evaluation all fail to require the subtype compatibility check that occurs when a subtype indication is elaborated (and for object declarations even the constraint elaboration is omitted). This check is certainly needed in these cases as well. The fix for this oversight is to define each of these rules to include the elaboration of the subtype indications for components with per-object constraints (which also subsumes the elaboration of the constraint itself).

One other minor gap is that the case of elaborating a named discriminant association within a per-object constraint is not covered by that rule in 3.8(18). The rule as given only describes a single evaluation for each expression of the constraint, but the intent is that for a named association the expression should be evaluated for each associated component.




8652/0003 - Modular types on one's complement machines

Working Reference Number AI95-00095
Report Qualifier -- Clarification Required
Section References
3.5.4

Question

How should an implementation on a one's complement machine implement modular types intended to use all the bits of a full word?

Summary of Response

Implementation Permission: On a one's complement machine, the implementation may support non-binary moduli above System.Max_Nonbinary_Modulus.

Corrigendum Wording

Insert after 3.5.4(27):

the new paragraph:

Response

Consider a 36-bit one's complement machine. One should be able to declare a 36-bit modular type. For logical operations to make sense, the all-ones bit pattern ought to be allowed, and should compare not equal to zero, and greater than every other bit pattern. The Implementation Permission in 3.5.4(27) is intended to allow this.

On a 36-bit two's complement machine, one would declare:

and T'Modulus would be 2**36, and the base range of T would be 0..2**36-1. If one says:

TT'Modulus is 2**36-1, and the base range of TT is usually 0..2**36-2. The implementation permission says that the base range of TT can be 0..2**36-1. This means that the all-ones bit pattern is a valid value of the type, and is not reduced via the modulus.




8652/0004 - S'Digits when T'Machine_Radix is 10

Working Reference Number AI95-00203
Report Qualifier -- Error
Section References
3.5.8

Question

The relationship given in 3.5.8(2) in the case of T'Machine_Radix = 10 implies that S'Digits + 1 = T'Model_Mantissa in such a case. Is this correct? (No.)

Summary of Response

The relationship between S'Digits and T'Model_Mantissa given in 3.5.8(2) states that S'Digits is the largest value of d for which

This allows for a "guard digit" which is necessary to take care of extreme circumstances that arise if the Machine_Radix is not decimal (as is usually the case).

However, this guard digit is unnecessary if Machine_Radix is 10 or a power of 10 and in such a case the relationship should read

If Machine_Radix is 10 this becomes simply

so that S'Digits = T'Model_Mantissa.

Corrigendum Wording

Replace 3.5.8(2):

by:

Discussion

This question echoes back to a change made between 1980 preliminary Ada and the 1983 standard which is worth explaining as background.

In Ada 83, the user specified a number D of decimal digits and the implementation then provided model numbers using B binary digits. Intuitively one might expect to need log 10 / log 2 (3.3219...) binary digits for every decimal digit (with appropriate rounding up). The 1980 edition of the Ada Reference Manual (3.5.7 third paragraph) says

So 1 decimal digit might be expected to be equivalent to 4 binary digits, 2 decimal digits equivalent to 7 binary digits and so on. But this is not enough. Four binary digits give a relative precision of between 1 in 8 and 1 in 16 whereas one decimal digit requests a maximum precision of 1 in 10. Thus there are places where the model numbers for B = 4 are slightly too far apart.

For example the decimal model numbers around 10000 for D = 1 are

whereas the binary model numbers for B = 4 are

and 8192 and 9216 are more than 1000 apart.

This surprising behaviour resulted in the addition of one to the formula so that 3.5.7(6) of Ada 83 concludes

In Ada 95 this formula has been generalized to use T'Machine_Radix rather than 2. However, the special case where Machine_Radix is 10 (or indeed a power of 10) has been overlooked since then no anomalous situations can arise and the "guard digit" is not required.

The formula should therefore be adjusted accordingly.

Note the peculiar phenomenon that more digits may be required for a hexadecimal machine than a decimal machine. Thus one decimal digit requires 2 hexadecimal digits.




8652/0005 - When is a Small clause allowed?

Working Reference Number AI95-00054
Report Qualifier -- Clarification Required
Section References
3.5.10

Question

3.5.9(8) says, "For a type defined by an ordinary_fixed_point_definition (an ordinary fixed point type), the small may be specified by an attribute_definition_clause (see 13.3)".

3.5.10(2) says, "Small may be specified for nonderived fixed point types via an attribute_definition_clause (see 13.3)".

13.3(5) says, "An attribute_designator is allowed in an attribute_definition_clause only if this International Standard explicitly allows it".

What is the intent? May Small be specified for a derived fixed point type? (No.) May it be specified for a decimal type? (No.)

Summary of Response

A Small clause is illegal for a decimal fixed point type. A Small clause is illegal for a derived fixed point type.

Corrigendum Wording

Replace 3.5.10(2):

by:

Response

A Small clause is illegal for a decimal fixed point type. A Small clause is illegal for a derived fixed point type.

Discussion

The intent was to disallow a Small clause for a decimal type, because the Small is determined by the type declaration.

The intent was to also disallow a Small clause for a derived fixed point type, because otherwise the model numbers of the parent and derived types might differ, resulting in semantic difficulties.




8652/0006 - The word "prefix" should be in sans serif font

Working Reference Number AI95-00030
Report Qualifier -- Presentation
Section References
3.6.2

Question

Shouldn't the word "prefix" be in the sans serif font? (Yes.)

Summary of Response

The word "prefix" should be in the sans serif font.

Corrigendum Wording

Replace 3.6.2(2):

by:

Discussion

This was an editing error.




8652/0007 - unknown_discriminant_parts on generic formal types

Working Reference Number AI95-00098
Report Qualifier -- Omission
Section References
3.7

Question

12.5(10) (a NOTE) says that "A discriminant_part is allowed only for certain kinds of types, and therefore only for certain kinds of generic formal types. See 3.7."

Unfortunately, the rule in 3.7(8) only applies to known_discriminant_parts. 3.7 does not contain any rule restricting the usage of unknown_discriminant_parts.

Various syntax rules usually do the job, but for generic formal types, the syntax allows unknown_discriminant_parts. Therefore, are the following legal? (No.)

Summary of Response

A generic formal type must not have an unknown_discriminant_part, unless the type is a composite non-array type.

Corrigendum Wording

Replace 3.7(8):

by:

Discussion

The intent is that elementary and array types cannot have discriminant parts (known or unknown).




8652/0008 - Aliased objects cannot have discriminants modified

Working Reference Number AI95-00168
Report Qualifier -- Error
Section References
3.7.1; 4.6

Question

Consider the following code fragment:

This example illustrates a case where it is possible to change the discriminant of an aliased component of an object, which is supposed to be forbidden.

Summary of Response

A view conversion of an array object is illegal if the target subtype and the operand do not have both aliased components or both non-aliased components.

A discriminant constraint for a general access type is illegal if there are places where the designated subtype appears constrained and others where it appears unconstrained.

Corrigendum Wording

Replace 3.7.1(7):

by:

Replace 4.6(11):

by:

Replace 4.6(12):

by:

Discussion

The problem (1) comes from the fact that it is possible to use a view conversion to convert an array object with aliased components to an array type with non-aliased components. Such a conversion must be disallowed.

The ARG also discussed the following example, which illustrates another case where the standard seems to allow a discriminant to be changed:

The root of problem (2) is that there are places (e.g., the visible part of P) where P.T is constrained, but other places (e.g., the private part and body of P) where P.T is unconstrained. This causes privacy problems when applying the following rule:

"if a component_definition contains the reserved word aliased and the type of the component is discriminated, then the nominal subtype of the component shall be constrained." (3.6(11))

Also note that the problem exists with non-private types, provided that the characteristic that the type is unconstrained is not visible everywhere:

One way to fix this problem would be to require a component-by-component check on the assignment to Q.X, but that would be very expensive. Moreover, a compile-time check would clearly be better than a run-time check.

Aliasedness of the components is not really what is causing trouble, though. It is really the existence of a general access type, and in fact of a discriminant constraint on such an access type, which causes trouble. Thus, forbidding such a constraint is the chosen solution, especially considering that constraints on access types are not a terribly useful feature.




8652/0009 - Attribute definition clause for stream attributes

Working Reference Number AI95-00137
Report Qualifier -- Error
Section References
3.8; 3.11; 9.1; 9.4; 13; 13.1; 13.3; 13.4; 13.11; 13.13.2; 13.14

Question

13.1(10) seems to forbid the following example:

Summary of Response

13.1(10) says:

This rule does not apply to an attribute_definition_clause for one of the stream-oriented attributes Read, Write, Input, and Output.

Corrigendum Wording

Replace 3.8(5):

by:

Replace 3.11(4):

by:

Replace 9.1(5):

by:

Replace 9.1(12):

by:

Replace 9.4(5):

by:

Replace 9.4(8):

by:

Replace 13(1):

by:

Replace the title of 13.1:

by:

Replace 13.1(1):

by:

Replace 13.1(2):

by:

Replace 13.1(4):

by:

Replace 13.1(5):

by:

Replace 13.1(6):

by:

Insert after 13.1(8):

the new paragraph:

Insert after 13.1(9):

the new paragraph:

Replace 13.1(11):

by:

Replace 13.1(13):

by:

Replace 13.1(19):

by:

Replace the title of 13.3:

by:

Replace 13.3(1):

by:

Replace 13.3(5):

by:

Replace 13.3(9):

by:

Replace 13.3(74):

by:

Replace 13.4(11):

by:

Replace 13.11(12):

by:

Replace 13.13.2(1):

by:

Replace 13.14(19):

by:

Discussion

The intent of 13.1(10) is to forbid two types from having different representation in certain cases. However, the stream-oriented attributes, although they are formally defined to be "representation attributes", do not actually affect the representation of the type. Therefore, there is no need for 13.1(10) to apply to these attributes. Furthermore, as the example illustrates, applying the rule to these attributes would seriously hinder their usefulness.

The definition of stream attributes as "representation attributes" has proven to be a continuing problem. Several issues have made it necessary to exempt stream attributes from the rules for representation attributes; indeed the number of such exemptions makes it clear that it is confusing to classify them as representation attributes. Therefore, we have taken the major step of defining a new kind of attribute, the "operational attributes", and redefining stream attributes to be of this kind.

In particular, 7.3(5), 13.1(10), and the last sentence of 13.1(11) are unchanged, so that these rules do not apply to operational items. None of these rules are necessary for these attributes. We've also left 3.8(11) unchanged, as an operational item cannot occur here. Changes to 13.1(15) and 13.1(18) are found in 8652/0040 (AI-00108).




8652/0010 - Expected type of a 'Access attribute

Working Reference Number AI95-00127
Report Qualifier -- Error
Section References
3.9.2; 3.10.2; 4.8

Question

Consider the following code fragment:

The call at (3) is clearly legal, and is a dispatching call.

However, the call at (1) appears to be illegal. The expected type for Y'Access is the anonymous type "access T", by 6.4.1(3). 3.10.2(24) says, "If the designated type of A [here, A is the anonymous access type] is tagged, then the type of the view [Y] shall be covered by the designated type". The type of the view is T'Class, which is not covered by the designated type, which is T. Therefore, Y'Access is illegal here.

The call at (2) appears to be illegal for the same reason.

It would seem that the same rules should apply to all of these calls; (1) and (2) should be legal, and should be dispatching calls.

Summary of Response

An attribute reference of the Access attribute may be used as the actual parameter in a dispatching call, if the formal is an access parameter designating a tagged type, and the prefix of the attribute reference is of the corresponding class-wide type. Such an actual is considered to be dynamically tagged.

An analogous rule applies to an attribute reference of Unchecked_Access and to an allocator.

Corrigendum Wording

Replace 3.9.2(7):

by:

Replace 3.9.2(9):

by:

Replace 3.10.2(24):

by:

Replace 3.10.2(27):

by:

Replace 4.8(3):

by:

Discussion

The rules should be equivalent in these cases; anything else would be surprising to the programmer. This is achieved by the above wording.

In the call at (1), Y'Access is of the anonymous type "access T". Y'Access is dynamically tagged, despite the fact that its type's designated type is not class-wide.

In the call at (2), new T'Class'(...) is also of the anonymous type "access T", and is also dynamically tagged.

Thus, all three calls are legal, and are dispatching calls to P.

No wording changes are needed for Unchecked_Access, since it is already defined in terms of Access.




8652/0011 - Calling conventions

Working Reference Number AI95-00117
Report Qualifier -- Omission
Section References
3.9.2; 6.3.1; 13.1

Question

6.3.1(2-13) define the default convention of various entities (that is, the convention in the absence of a convention-specifying pragma):

-----------------

1. What is the default convention of an entity not covered by 6.3.1, such as a record type? (Ada.)

-----------------

2. Does an inherited or overriding subprogram have (by default) the same convention as the parent subprogram? (Yes.)

6.3.1(3) implies that if the calling convention of a parent subprogram is not Ada, the default convention of an overriding subprogram is, nonetheless, Ada. However, 3.9.2(10) says:

6.3.1(17) requires matching conventions for subtype conformance. Thus, the default calling convention for this overriding case is illegal; the programmer must give a pragma specifying the convention in this case. This seems unfriendly.

On the other hand, 3.4(18) says:

And 6.1(22) says:

These paragraphs seem to imply that an inherited subprogram inherits the calling convention of its parent, as part of the inherited profile.

-----------------

3. Is an implicitly declared dispatching "/=" operator legal? (Yes.)

Paragraph 3.9.1(1) says that the primitive subprograms of a tagged type are called dispatching operations. Paragraph 3.9.2(10) goes on to say that a dispatching operation shall not be of convention Intrinsic. However, paragraph 6.3.1(6) says that "/=" declared implicitly due to the declaration of "=" is of convention Intrinsic, by default.

Together these imply that the "/=" implicitly declared due to the declaration of "=" of a tagged type is an illegal dispatching operation. Is this the intent? (No.)

Summary of Response

Unless specified otherwise in the standard, the default convention of any entity is Ada.

An inherited or overriding subprogram of a type extension inherits the calling convention of the parent subprogram.

New operations of type extensions have the convention of their type unless a new convention is defined for the operation, if this is supported by an implementation.

The convention of the partial view of a private type or private extension is the convention of the full type.

An explicitly declared dispatching operation shall not have convention Intrinsic. However, an implicitly declared dispatching "/=" operator with Boolean result legally has convention Intrinsic.

Corrigendum Wording

Replace 3.9.2(10):

by:

Replace 6.3.1(2):

by:

Insert after 6.3.1(13):

the new paragraph:

Replace 13.1(11):

by:

Discussion

1. The default convention ought to be Ada for any entity not covered by 6.3.1. The dispatching operations of a type ought to inherit the convention of the type, for convenient interfacing to other OOP languages. (See below for more discussion of this point.)

-----------------

2. It is important that Ada allow clean interfaces to other programming languages. In particular, it is important that Ada's tagged types can be used to interface to other OOP languages.

If an Ada implementation is tightly integrated with another language, such as C++ or Java, it is nice if an Ada tagged type can be declared as an extension of a (foreign) type (or class) of the other language. Presumably, all of the dispatching operations of this foreign type would be defined as imported, with the convention of that other language. When defining the type extension in Ada, it would be very inconvenient if every overriding needed a pragma Convention on it to match that of the inherited operation, as required by 3.9.2(10).

Hence, it seems appropriate to define the default calling convention of an overriding of an inherited dispatching operation to be the same as that of the corresponding operation on the parent type, rather than always being convention "Ada" as specified in 6.3.1(3).

For example:

The "pragma Convention(Java, ...);" should be implicit when overriding a dispatching operation with convention Java. Anything else would be illegal by 3.9.2(10), and it seems silly to require the programmer to litter their program with redundant "pragma Convention"s.

The Note B.1(42) - derived from 13.1 - implies permission of implementation-defined restrictions of interfacing pragmas. Hence an implementation will be allowed to reject the attempt to create "heterogeneous" tagged types, i.e., types having primitive operations of different, explicitly specified conventions or of explicitly specified conventions different from the convention of the type.

2.a. The "Breach of Privacy" Issue

Presently, the convention of a primitive subprogram can be specified in the private part of the declaring package. The current rules require explicit confirmation of this convention for overriding subprograms and thus constitute a breach of the privacy of the private part, since the user needs to know about this privately specified convention in order to make the overriding declaration legal.

We are very reluctant to mandate Convention pragmas in the visible part of the package. Although such a rule might be derivable from freezing rules, it nevertheless could create a compatibility problem for existing code.

The proposed new rule of inheriting the convention eases, but does not eliminate, the breach of privacy, as any explicitly specified convention will still need to confirm the inherited convention.

At the implementation level, both the existing and the proposed model breach the private part, as subtype conformance of overriding with inherited subprograms includes checking for equality of the convention.

2.b. Deriving the convention of operations from the type

Having dispatching operations with the convention of some other OOP language, while the type is not represented according to the convention of this other language, will be almost impossible to implement. The "normal" case will be that both type and operations need the convention pragma. In this context, it makes little sense that the convention of primitive operations defaults to Ada rather than to the convention of their type. The user will be forced to repeat the pragma for all the operations of the type. Considerably more convenient is a model, in which the default convention of dispatching operations is inherited from the type, but overridable if the implementation allows for such mixed conventions.

Since current rules imply that the convention of a type needs to be specified for the full view of the type, such dependency creates yet another breach of privacy in the case of private tagged types. However, the breach already exists as explained in 2.a. and then to exploit it for more convenience to the user and a cleaner overall model seems justified.

Mandating the specification of the convention for the partial view in order to avoid the breach of privacy seems too much of an incompatibility for existing code.

2.c. The convention of a partial view

As mentioned previously, the current rules of the standard require that the convention be specified on the full view. So, what is the convention of a partial view? It is clear that a partial view and full view must have the same representation (including convention), since they are just views of the same entity. However, while this is obvious, it is also not mentioned in the standard. A statement to this effect needs to be added to 13.1.

-----------------

3. Clearly, an implicitly declared dispatching "/=" should not automatically be illegal.

The proposed new wording precludes declaring a dispatching operation by renaming the Intrinsic "/=", which is good (since there is no real body associated with "/="). It does not make "/=" itself illegal, which is also good.

The reason for 6.3.1(4-10) making various subprograms Intrinsic is that these subprograms don't really exist in machine code. For example, an implementation would typically not generate any code for the implicitly-declared "/=" operator -- instead, it would call the "=" operator, and then do a "not" operation at the call site. We don't want to allow 'Access of such subprograms, because it would introduce an implementation burden -- the implementation would have to materialize these subprograms as real machine-code subprograms, which is not otherwise necessary.

A similar issue arises with 6.3.1, which says that an inherited subprogram of a generic formal type with unknown discriminants is of convention Intrinsic, by default.

The reason for this rule is obscure enough that it should have been documented in the AARM: Consider:

Within Instance, all calls to Proc will be dispatching calls, so Proc doesn't really exist in machine code, so we wish to avoid taking 'Access of it. 6.3.1(8) applies to those cases where the actual type might be class-wide, and makes these Intrinsic, thus forbidding 'Access.

The wording change to 3.9.2(10) shown above means that it is permitted to have such an inherited subprogram. If the specification of G contained a type extension of Formal, then that type's inherited Proc would also have convention Intrinsic, which would be legal. However, an explicit overriding of that Proc would be illegal.




8652/0012 - Derived access types share the same pool

Working Reference Number AI95-00062
Report Qualifier -- Omission
Section References
3.10

Question

NOTE 3.4(31) says, "If the parent type is an access type, then the parent and the derived type share the same storage pool..." This is clearly what we want, but I can't seem to prove it from the real rules (i.e. non-NOTES).

Summary of Response

A derived access type shares its parent's storage pool.

Corrigendum Wording

Replace 3.10(7):

by:

Response

A derived access type shares its parent's storage pool.

Discussion

NOTE 3.4(31) makes the intent clear.

Furthermore, 13.11.2(16) says, "The execution of a call to an instance of Unchecked_Deallocation is erroneous if the object was created other than by an allocator for an access type whose pool is Name'Storage_Pool."

Thus, if a derived access type does not have the same pool as its parent, then the following would be erroneous:

The above was not erroneous in Ada 83. This would be a serious upward incompatibility, which there was no intention to introduce.

Note that no such upward incompatibility is documented in the AARM.




8652/0013 - The first subtype of a type defined by an access[_type]_definition

Working Reference Number AI95-00012
Report Qualifier -- Error
Section References
3.10

Question

3.10(14) says:

However, access_type_definition includes access_to_object_definition. What is the intent?

Summary of Response

The second sentence of 3.10(14) applies to all access-to-object types, including those defined by access_definitions.

Corrigendum Wording

Replace 3.10(14):

by:

Discussion

The notion of designated subtype doesn't make sense for access-to-subprograms. The intent is that this rule should apply to all access-to-object types. Apparently, access_type_definition is a "typo".

Another typo was noted in this paragraph. The paragraph says "...if the designated subtype is an unconstrained array or discriminated type...", but this clearly should say "...discriminated {sub}type...".




8652/0014 - Elaboration checks for renamings-as-body

Working Reference Number AI95-00064
Report Qualifier -- Omission
Section References
3.11; 3.11.1; 8.5.4; 13.14

Question

3.11(10) indicates that an elaboration check is required only when a subprogram has an explicit body that is a subprogram_body. However, when a renaming declaration is used as a body, it is possible for the elaboration of the renaming declaration to require the evaluation of a name, such as X.all, that implies some sort of elaboration check should be performed. For example:

In the above, clearly we need to wait until the expression "Z.all" is evaluated before F can be safely called. However, it is not clear that any check for this is required by 3.11(10).

By the way, where is "body" defined? It presumably includes entry body, and perhaps renaming-as-body. However, only the syntactic entity BODY is defined (in 3.11). Where is the unbolded term "body" defined?

Summary of Response

An elaboration check is performed for a call to a subprogram whose body is given as a renaming-as-body. This check fails if the renaming-as-body has not yet been elaborated. (As usual, an elaboration check is also performed for the renamed subprogram, and fails if its body has not yet been elaborated.)

Corrigendum Wording

Replace 3.11(10):

by:

Replace 3.11.1(1):

by:

Insert before 8.5.4(8):

the new paragraph:

Replace 13.14(3):

by:

Discussion

Since the elaboration of a renaming-as-body may evaluate expressions, it is clearly necessary that this elaboration be performed before calling the subprogram. Therefore, an elaboration check should be done on a subprogram whose body is a renaming-as-body, not just when the body is a subprogram_body.

It seems that the right model for renaming-as-body that occurs after the subprogram is frozen should be that of a wrapper subprogram, with its own elaboration flag.

Taken together, these rules imply that when calling a subprogram whose body is a renaming-as-body, a check will be made that the renaming-as-body has been elaborated, and also that the body of the renamed subprogram has been elaborated. Furthermore, if the renamed subprogram is in turn completed by another renaming-as-body, the body of that third subprogram will also be checked; the rule is transitive.

See 8652/0027 (AI-00135) for a discussion of circularities involving renamings-as-body.

This issue also adds the missing definition of the semantic term "body". This change makes a renaming-as-body a body. However, doing so triggers the freezing rule 13.14(3): "A noninstance body other than a renaming-as-body causes freezing of each entity declared before it within the same declarative_part." It clearly was the intent of the designers of the language that renaming-as-body not freeze (otherwise the second sentence of 8.5.4(5) could never be true), and existing compilers do not freeze when a renaming-as-body is encountered. We do not want to change this behavior, so we add an exception to 13.14(3).




8652/0015 - Float_Type'Small

Working Reference Number AI95-00093
Report Qualifier -- Omission
Section References
4.1.4

Question

Paragraph 4.1.4(12) says:

AARM J(1.d) lists several Ada 83 floating-point attributes that have been removed from the language, including 'Small; AARM J(1.h), however, says that "Implementations can continue to support the above features for upward compatibility".

Since 'Small is a language-defined attribute for fixed-point types, 4.1.4(12) implies that an implementation must not provide a 'Small attribute for floating-point types. This clearly contradicts the intent of J(1).

May an implementation support the 'Small attribute for floating-point types? (Yes.)

Summary of Response

An implementation may support an implementation-defined attribute Small for floating point types.

Corrigendum Wording

Replace 4.1.4(12):

by:

Discussion

The intent is that implementations be allowed to support all Ada 83 attributes, for upward compatibility. Thus, it is important that they be allowed to support the Small attribute on floating point types. Therefore, this resolution makes a specific exception to the rule in 4.1.4(12).




8652/0016 - Equality for composite types

Working Reference Number AI95-00123
Report Qualifier -- Clarification Required
Section References
4.5.2

Question

The following language-defined types are private, and have an explicitly defined primitive "=" operator:

This would seem to imply that the composability of these "=" operators depends on whether the implementation chooses to implement them as tagged types, by 4.5.2(14-15):

and by 4.5.2(21-24):

This would cause portability problems.

Also, in the above definition, what does "in terms of" mean? For a composite type, if some parts have an "=" with side effects, does the language define whether all of these side effects happen, and in what order?

Summary of Response

The primitive equality operators of a language-defined type compose properly (i.e., do not "reemerge"), when the type is used as a component type, or a generic actual type.

For any composite type, the order in which "=" is called for components is not defined by the language. Furthermore, if the result can be determined before calling "=" on some components, the language does not define whether "=" is called on those components.

Corrigendum Wording

Insert after 4.5.2(24):

the new paragraph:

Insert after 4.5.2(32):

the new paragraph:

Discussion

Composability of equality for a type T means three things:

Non-composability means that the predefined equality is called for T, despite the fact that T has a user-defined equality operator. Of course, if there is no user-defined equality, then equality always composes properly.

Item 3 is irrelevant here, since none of the types in question is (visibly) tagged.

For a private type, if the underlying type is tagged, or if there is no user-defined equality, then equality composes. Otherwise, it does not. (Here, "underlying type" means the full type, or if that comes from a private type, then the underlying type of that type, and so on.)

However, for the private types mentioned in the question, the standard does not specify whether the underlying type is tagged, nor whether the equality operator is truly user-defined (as opposed to just being the normal bit-wise equality).

It is important that the composability of "=" for these types be defined by the language. We choose to make them composable. An implementation can achieve this by making the full type tagged. Alternatively, the implementation could simply use the predefined "=" for these types. (Alternatively, an implementation could treat these types specially, making them untagged, but with composable equality. However, this would add some complexity to the compiler.)

Here is an analysis of implementation concerns for each type in question:

As to the second question, the standard clearly does not define any order of calling "=" on components, nor does it say whether the results are combined with "and" or "and then". Equality operators with side effects are questionable in any case, so we allow implementations freedom to do what is most convenient and/or most efficient. Consider equality of a variant record: The implementation might first check that the discriminants are equal, and if not, skip the component-by-component comparison. Alternatively, the implementation might first compare the common elements, and then check the discriminants. A third possibility is to first compare some portions with a bit-wise equality, and then (conditionally) call user-defined equality operators on the other components. All of these implementations are valid.




8652/0017 - Definiteness and type derivation

Working Reference Number AI95-00184
Report Qualifier -- Error
Section References
4.6; 8.5.1

Question

The definiteness of a type is not preserved by type derivation. A type with defaulted discriminants may be derived from a type without defaulted discriminants and vice-versa.

This makes it possible to rename a component of a record that later disappears due to an assignment to the enclosing object, as shown in the following examples:

1 - An example where the parent type is indefinite and the derived type is definite:

The declaration of C1_Ren in the generic G is legal as per 8.5.1(5), because the formal type F is indefinite. But when G is instantiated with type T2, the actual type is definite, so now we have renamed a component that may disappear by assignment to the variable Y. Note that the declaration of C1_Ren might be in the body of G, so we cannot avoid this problem by rechecking 8.5.1(5) on the instantiation.

2 - An example where the parent type is definite and the derived type is indefinite:

Assume that the implementation chooses to pass X by reference. Then, 6.4.1(10) says that there is an implicit view conversion to Indefinite_Child, and the formal parameter X then denotes the result of this view conversion. The result of the explicit view conversion is unconstrained, and the result of the implicit view conversion is also unconstrained, hence X is unconstrained, which violates the language design principle of the NOTE in 3.7(28).

One of the unpleasant consequences of this violation is that the assignment to X doesn't raise an exception, and after the execution of this assignment C denotes a non-existent component.

Note that if the implementation chooses to pass by copy, then there is an implicit value conversion -- see 6.4.1(11). So in that case, there's no problem.

Summary of Response

The legality rules about object renaming are checked in the private part of an instance. In a generic body, they are checked in an assume-the-worst manner: it is illegal to rename a component that depends on a discriminant of a variable whose nominal subtype is an untagged indefinite generic formal derived type (or a descendant of such a type) unless the variable is aliased.

A view conversion to an indefinite object is constrained.

For a conversion of an object name to a tagged type to be a view conversion, the object's nominal subtype has to be tagged.

Corrigendum Wording

Replace 4.6(5):

by:

Replace 4.6(54):

by:

Replace 8.5.1(5):

by:

Discussion

The fix for example 1 is to forbid the renaming: even though the formal type looks indefinite, it is possible for the actual type to be definite. Note that the manual already covers the case where C1_Ren is declared in the visible part of the generic unit, because legality rules are checked in the instance (12.3(11)). We are extending the legality rules for object renaming to apply in the private part of the instance, and we are assuming the worst in the body.

To fix example 2, we could forbid a view conversion that obtains an indefinite view of an object whose nominal subtype is definite. However, such a view conversion was legal in Ada 83, so this would be an incompatibility. It seems better to mandate a check on the assignment to X: it is very surprising that this check is not there in the first place.

Also consider the following example:

This is similar to example 2 above, except that here we don't use a view conversion to change the discriminant of Q.X. In this case the trouble comes from the view conversion T (Q.X) in the declaration of C_Ren. As long as all the types involved are tagged, renaming a component of a view conversion works fine, because tagged types don't have defaulted discriminants. But here we go through an untagged type to change the discriminants. It is clear that the conversion T (Q.X) should not be considered a view conversion.




8652/0018 - Full conformance of expressions with attributes

Working Reference Number AI95-00175
Report Qualifier -- Omission
Section References
6.3.1

Question

Is Integer'Succ fully conformant with Integer'Pred? (No.)

From 6.3.1(19-22), it would appear so: both attribute_references have the syntactic construction

Summary of Response

For two attribute_references to fully conform, the attribute_designator must be the same.

Corrigendum Wording

Insert after 6.3.1(21):

the new paragraph:

Discussion

It would be ludicrous to treat two different attributes to be fully conformant. None of the reasons for conformance checking would be enforced if this were true. Thus, the standard's failure to require this can only be categorized as an oversight.




8652/0019 - Delayed declaration of inherited primitive subprograms

Working Reference Number AI95-00033
Report Qualifier -- Error
Section References
7.3.1

Question

Is the rule given in 7.3.1(6) intended to apply to cases where a derived type is declared outside the declarative region in which its parent type is immediately declared? (No.)

Consider the following example:

Also, are the rules of 7.3.1(3) and 7.3.1(4) regarding the availability of additional charac