In Ada 2012, static matching of subtypes requires that the static predicates that apply to the subtypes come from the same declaration.
Compiling predmatch.ads in Ada 2012 mode must yield: predmatch.ads:5:21: object subtype must statically match designated subtype predmatch.ads:12:22: object subtype must statically match designated subtype predmatch.ads:15:22: object subtype must statically match designated subtype --- package Predmatch is type Int_Ref is access all Integer; subtype Even is Integer with Dynamic_predicate => Even mod 2 = 0; X1 : aliased Even; Ptr : Int_Ref := X1'access; -- Illegal in Ada 2012 subtype Little_Even is Integer with Static_Predicate => Little_Even in 2 | 4 | 8 | 16; X2 : aliased Little_Even; Ptr2 : Int_Ref := X2'Access; -- illegal in Ada 2012 type Pos_Ref is access all Positive; Ptr3 : Pos_Ref := X1'access; -- Illegal in Ada 2005 subtype Mult2 is Even; type Mult_Ref is access all Mult2; Ptr4 : Mult_Ref := X1'Access; -- OK, same predicate end Predmatch; Tested on x86_64-pc-linux-gnu, committed on trunk 2012-05-15 Ed Schonberg <schonb...@adacore.com> * sem_eval.adb (Subtypes_Statically_Match): In Ada 2012, static matching requires matching of static subtype predicates as well.
Index: sem_eval.adb =================================================================== --- sem_eval.adb (revision 187504) +++ sem_eval.adb (working copy) @@ -4664,6 +4664,41 @@ -- values match (RM 4.9.1(1)). function Subtypes_Statically_Match (T1, T2 : Entity_Id) return Boolean is + + function Predicates_Match return Boolean; + -- In Ada 2012, subtypes statically match if their static predicates + -- match as well. + + function Predicates_Match return Boolean is + Pred1 : Node_Id; + Pred2 : Node_Id; + + begin + if Ada_Version < Ada_2012 then + return True; + + elsif Has_Predicates (T1) /= Has_Predicates (T2) then + return False; + + else + Pred1 := Get_Rep_Item_For_Entity (T1, Name_Static_Predicate); + Pred2 := Get_Rep_Item_For_Entity (T2, Name_Static_Predicate); + + -- Subtypes statically match if the predicate comes from the + -- same declaration, which can only happen if one is a subtype + -- of the other and has no explicit predicate. + + -- Suppress warnings on order of actuals, which is otherwise + -- triggered by one of the two calls below. + + pragma Warnings (Off); + return Pred1 = Pred2 + or else (No (Pred1) and then Is_Subtype_Of (T1, T2)) + or else (No (Pred2) and then Is_Subtype_Of (T2, T1)); + pragma Warnings (On); + end if; + end Predicates_Match; + begin -- A type always statically matches itself @@ -4736,7 +4771,7 @@ -- If the bounds are the same tree node, then match if LB1 = LB2 and then HB1 = HB2 then - return True; + return Predicates_Match; -- Otherwise bounds must be static and identical value