Child Package Library-Level Renaming of a Pure Package

Consider these packages:

package Pureness is
   I : Integer;
end Pureness;

with Ada.Strings;
package Pureness.Child renames Ada.Strings;

The variable in Pureness ensures that it cannot be considered Pure.

Compiler G accepts these without complaint. Compiler O rejects Pureness.Child, saying it relies on its parent, Pureness, which is not Pure, and Ada.Strings is Pure and so cannot depend on Pureness.

I think that O is incorrect because of ARM 10.1.1(11):

The children of a library unit occur immediately within the declarative region of the declaration of the library unit.

Since the renaming is legal if put in the specification of Pureness, it should be legal as a child unit as well.

However, IANALL, so I would like to hear what the language lawyers among us think.

G (presumably GNAT) is incorrect here. The issue if with elaboration ordering. All pure units must be elaborated before other units, but Pureness must also be elaborated before Pureness.Child because it is its parent. Obviously both constraints can not be satisfied at the same time.

If you look at 10.1.1(11.a) you’ll see that:

Reason: These definitions are worded carefully to avoid defining subunits as children. Only library units can be children.

Since it is not a child (i.e. its own unit) it never becomes a part of elaboration ordering so we do not have the same problem. I assume you also can not explicitly give a subunit a Pure pragma/attribute, but I have not checked that.

I was also able to come up with one observable bug from this:

  1. Add a body to Pureness that calls Ada.Text_IO.Put_Line
  2. Create another package that is declared Pure but depends on Pureness.Child
  3. Observe that depending on a pure package that is not even a child of Pureness now causes a call to Put_Line, which it obviously should not be able to do