[Ada] Implement AI12-0077 Has_Same_Storage on objects of size zero
authorEric Botcazou <ebotcazou@adacore.com>
Mon, 30 Mar 2020 10:38:01 +0000 (12:38 +0200)
committerPierre-Marie de Rodat <derodat@adacore.com>
Mon, 15 Jun 2020 08:04:19 +0000 (04:04 -0400)
2020-06-15  Eric Botcazou  <ebotcazou@adacore.com>

gcc/ada/

* exp_attr.adb (Expand_N_Attribute_Reference) <Has_Same_Storage>:
Do not do superfluous work.  Add the condition (X'Size /= 0) on
both paths and turn binary AND into short-circuit AND THEN.

gcc/ada/exp_attr.adb

index 5faa1ce..a7b9007 100644 (file)
@@ -3603,6 +3603,7 @@ package body Exp_Attr is
 
          --    (X'address = Y'address)
          --      and then (X'Size = Y'Size)
+         --      and then (X'Size /= 0)      (AI12-0077)
 
          --  If both arguments have the same Etype the second conjunct can be
          --  omitted.
@@ -3622,27 +3623,39 @@ package body Exp_Attr is
              Attribute_Name => Name_Size,
              Prefix         => New_Copy_Tree (X));
 
-         Y_Size :=
-           Make_Attribute_Reference (Loc,
-             Attribute_Name => Name_Size,
-             Prefix         => New_Copy_Tree (Y));
-
          if Etype (X) = Etype (Y) then
             Rewrite (N,
-              Make_Op_Eq (Loc,
-                Left_Opnd  => X_Addr,
-                Right_Opnd => Y_Addr));
+              Make_And_Then (Loc,
+                Left_Opnd  =>
+                  Make_Op_Eq (Loc,
+                    Left_Opnd  => X_Addr,
+                    Right_Opnd => Y_Addr),
+                Right_Opnd =>
+                  Make_Op_Ne (Loc,
+                    Left_Opnd  => X_Size,
+                    Right_Opnd => Make_Integer_Literal (Loc, 0))));
          else
+            Y_Size :=
+              Make_Attribute_Reference (Loc,
+                Attribute_Name => Name_Size,
+                Prefix         => New_Copy_Tree (Y));
+
             Rewrite (N,
-              Make_Op_And (Loc,
+              Make_And_Then (Loc,
                 Left_Opnd  =>
                   Make_Op_Eq (Loc,
                     Left_Opnd  => X_Addr,
                     Right_Opnd => Y_Addr),
                 Right_Opnd =>
-                  Make_Op_Eq (Loc,
-                    Left_Opnd  => X_Size,
-                    Right_Opnd => Y_Size)));
+                  Make_And_Then (Loc,
+                    Left_Opnd  =>
+                      Make_Op_Eq (Loc,
+                        Left_Opnd  => X_Size,
+                        Right_Opnd => Y_Size),
+                    Right_Opnd =>
+                      Make_Op_Ne (Loc,
+                        Left_Opnd  => New_Copy_Tree (X_Size),
+                        Right_Opnd => Make_Integer_Literal (Loc, 0)))));
          end if;
 
          Analyze_And_Resolve (N, Standard_Boolean);