sem_eval.ads, [...] (Subtypes_Statically_Match): Return False if Esize values do...
authorRobert Dewar <dewar@adacore.com>
Wed, 19 Feb 2014 11:01:01 +0000 (11:01 +0000)
committerArnaud Charlet <charlet@gcc.gnu.org>
Wed, 19 Feb 2014 11:01:01 +0000 (12:01 +0100)
2014-02-19  Robert Dewar  <dewar@adacore.com>

* sem_eval.ads, sem_eval.adb (Subtypes_Statically_Match): Return False
if Esize values do not match.

From-SVN: r207889

gcc/ada/ChangeLog
gcc/ada/gnat_rm.texi
gcc/ada/sem_eval.adb
gcc/ada/sem_eval.ads

index 92b8355..243878d 100644 (file)
@@ -1,3 +1,8 @@
+2014-02-19  Robert Dewar  <dewar@adacore.com>
+
+       * sem_eval.ads, sem_eval.adb (Subtypes_Statically_Match): Return False
+       if Esize values do not match.
+
 2014-02-19  Yannick Moy  <moy@adacore.com>
 
        * sinfo.ads: Minor comment update.
index 89ed0d3..c9f575e 100644 (file)
@@ -3718,7 +3718,7 @@ This means that you can compile a program, and then without having to
 recompile the program, you can run it with different values being used
 for initializing otherwise uninitialized values, to test if your program
 behavior depends on the choice.  Of course the behavior should not change,
-and if it does, then most likely you have an erroneous reference to an
+and if it does, then most likely you have an incorrect reference to an
 uninitialized value.
 
 It is even possible to change the value at execution time eliminating even
@@ -8714,6 +8714,45 @@ alignment will be 4, because of the
 integer field, and so the default size of record objects for this type
 will be 64 (8 bytes).
 
+A consequence of this capability is that different object sizes can be
+given to subtypes that would otherwise be considered in Ada to be
+statically matching.  But it makes no sense to consider such subtypes
+as statically matching.  Consequently, in @code{GNAT} we add a rule
+to the static matching rules that requires object sizes to match.
+Consider this example:
+
+@smallexample @c ada
+ 1. procedure BadAVConvert is
+ 2.    type R is new Integer;
+ 3.    subtype R1 is R range 1 .. 10;
+ 4.    subtype R2 is R range 1 .. 10;
+ 5.    for R1'Object_Size use 8;
+ 6.    for R2'Object_Size use 16;
+ 7.    type R1P is access all R1;
+ 8.    type R2P is access all R2;
+ 9.    R1PV : R1P := new R1'(4);
+10.    R2PV : R2P;
+11. begin
+12.    R2PV := R2P (R1PV);
+               |
+       >>> target designated subtype not compatible with
+           type "R1" defined at line 3
+
+13. end;
+@end smallexample
+
+@noindent
+In the absence of lines 5 and 6,
+types @code{R1} and @code{R2} statically match and
+hence the conversion on line 12 is legal. But since lines 5 and 6
+cause the object sizes to differ, @code{GNAT} considers that types
+@code{R1} and @code{R2} are not statically matching, and line 12
+generates the diagnostic shown above.
+
+@noindent
+Similar additional checks are performed in other contexts requiring
+statically matching subtypes.
+
 @node Attribute Passed_By_Reference
 @unnumberedsec Attribute Passed_By_Reference
 @cindex Parameters, when passed by reference
@@ -14185,7 +14224,9 @@ an attribute definition clause.  Note that the use of these attributes
 can cause the RM 13.1(14) rule to be violated.  If two access types
 reference aliased objects whose subtypes have differing @code{Object_Size}
 values as a result of explicit attribute definition clauses, then it
-is erroneous to convert from one access subtype to the other.
+is illegal to convert from one access subtype to the other. For a more
+complete description of this additional legality rule, see the
+description of the @code{Object_Size} attribute.
 
 At the implementation level, Esize stores the Object_Size and the
 RM_Size field stores the @code{Value_Size} (and hence the value of the
index 51b84f6..629ce45 100644 (file)
@@ -4834,6 +4834,10 @@ package body Sem_Eval is
    --  they are the same identical constraint, or if they are static and the
    --  values match (RM 4.9.1(1)).
 
+   --  In addition, in GNAT, the object size (Esize) values of the types must
+   --  match if they are set. The use of 'Object_Size can cause this to be
+   --  false even if the types would otherwise match in the RM sense.
+
    function Subtypes_Statically_Match (T1, T2 : Entity_Id) return Boolean is
 
       function Predicates_Match return Boolean;
@@ -4852,9 +4856,13 @@ package body Sem_Eval is
          if Ada_Version < Ada_2012 then
             return True;
 
+         --  Both types must have predicates or lack them
+
          elsif Has_Predicates (T1) /= Has_Predicates (T2) then
             return False;
 
+         --  Check matching predicates
+
          else
             Pred1 :=
               Get_Rep_Item
@@ -4886,6 +4894,13 @@ package body Sem_Eval is
       if T1 = T2 then
          return True;
 
+      --  No match if sizes different (from use of 'Object_Size)
+
+      elsif Known_Static_Esize (T1) and then Known_Static_Esize (T2)
+        and then Esize (T1) /= Esize (T2)
+      then
+         return False;
+
       --  Scalar types
 
       elsif Is_Scalar_Type (T1) then
index fb1ebfa..312fac1 100644 (file)
@@ -222,7 +222,9 @@ package Sem_Eval is
 
    function Subtypes_Statically_Match (T1, T2 : Entity_Id) return Boolean;
    --  Determine whether two types T1, T2, which have the same base type,
-   --  are statically matching subtypes (RM 4.9.1(1-2)).
+   --  are statically matching subtypes (RM 4.9.1(1-2)). Also includes the
+   --  extra GNAT rule that object sizes must match (this can be false for
+   --  types that match in the RM sense because of use of 'Object_Size).
 
    function Compile_Time_Known_Value (Op : Node_Id) return Boolean;
    --  Returns true if Op is an expression not raising Constraint_Error whose