The presence of a body freezes all entities previously declared in the current list of declarations, but this does not apply if the body does not come from source. A type invariant is transformed into a subprogram body which is placed at the end of the private part of the current package, but this body does not freeze incomplete types that may be declared in this private part.
Tested on x86_64-pc-linux-gnu, committed on trunk 2011-11-23 Ed Schonberg <schonb...@adacore.com> * freeze.adb (Freeze_All_Ent): An incomplete type is not frozen by a subprogram body that does not come from source.
Index: freeze.adb =================================================================== --- freeze.adb (revision 181662) +++ freeze.adb (working copy) @@ -1342,7 +1342,9 @@ -- If an incomplete type is still not frozen, this may be a -- premature freezing because of a body declaration that follows. - -- Indicate where the freezing took place. + -- Indicate where the freezing took place. Freezing will happen + -- if the body comes from source, but not if it is internally + -- generated, for example as the body of a type invariant. -- If the freezing is caused by the end of the current declarative -- part, it is a Taft Amendment type, and there is no error. @@ -1360,8 +1362,9 @@ N_Protected_Body, N_Task_Body) or else Nkind (Bod) in N_Body_Stub) - and then - List_Containing (After) = List_Containing (Parent (E)) + and then + List_Containing (After) = List_Containing (Parent (E)) + and then Comes_From_Source (Bod) then Error_Msg_Sloc := Sloc (Next (After)); Error_Msg_NE