Fix uniqueness of address for aliased objects
authorEric Botcazou <ebotcazou@gcc.gnu.org>
Fri, 8 May 2020 15:18:20 +0000 (17:18 +0200)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Fri, 8 May 2020 15:25:12 +0000 (17:25 +0200)
Two aliased objects must have distinct addresses, even if they have
size zero, so we make sure to allocate at least one byte for them.

* gcc-interface/decl.c (gnat_to_gnu_entity) <E_Variable>: Force at
least the unit size for an aliased object of a constrained nominal
subtype whose size is variable.

gcc/ada/ChangeLog
gcc/ada/gcc-interface/decl.c
gcc/testsuite/ChangeLog
gcc/testsuite/gnat.dg/addr15.adb [new file with mode: 0644]

index 9644e018f3e825f3768a573233fec30ea6779996..35d111401e2923a33695300690f2244b2f010af1 100644 (file)
@@ -1,3 +1,9 @@
+2020-05-08  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * gcc-interface/decl.c (gnat_to_gnu_entity) <E_Variable>: Force at
+       least the unit size for an aliased object of a constrained nominal
+       subtype whose size is variable.
+
 2020-05-08  Eric Botcazou  <ebotcazou@adacore.com>
 
        * gcc-interface/decl.c (gnat_to_gnu_entity) <E_Array_Subtype>: Deal
index a4053eec8397cc5dd785505da5d3ee0e5ae1786a..9c1acd9f23f4532debaf76bdf84cc6a6affa7e4f 100644 (file)
@@ -969,10 +969,19 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
          align = MINIMUM_ATOMIC_ALIGNMENT;
 #endif
 
-       /* Make a new type with the desired size and alignment, if needed.
-          But do not take into account alignment promotions to compute the
-          size of the object.  */
+       /* Do not take into account aliased adjustments or alignment promotions
+          to compute the size of the object.  */
        tree gnu_object_size = gnu_size ? gnu_size : TYPE_SIZE (gnu_type);
+
+       /* If the object is aliased, of a constrained nominal subtype and its
+          size might be zero at run time, we force at least the unit size.  */
+       if (Is_Aliased (gnat_entity)
+           && !Is_Constr_Subt_For_UN_Aliased (gnat_type)
+           && Is_Array_Type (Underlying_Type (gnat_type))
+           && !TREE_CONSTANT (gnu_object_size))
+         gnu_size = size_binop (MAX_EXPR, gnu_object_size, bitsize_unit_node);
+
+       /* Make a new type with the desired size and alignment, if needed.  */
        if (gnu_size || align > 0)
          {
            tree orig_type = gnu_type;
index adacf69b027e54d4158c8dd7e6932ccce0d20ddd..8dc87d3948de3eba032b42c9d2b6343f8dd432c1 100644 (file)
@@ -1,3 +1,7 @@
+2020-05-08  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * gnat.dg/addr15.adb: New test.
+
 2020-05-08  Richard Biener  <rguenther@suse.de>
 
        * gnat.dg/opt83.adb: New testcase.
diff --git a/gcc/testsuite/gnat.dg/addr15.adb b/gcc/testsuite/gnat.dg/addr15.adb
new file mode 100644 (file)
index 0000000..bb79dff
--- /dev/null
@@ -0,0 +1,19 @@
+--  { dg-do run }
+
+with System; use System;
+
+procedure Addr15 is
+
+  function Get_Bound (Param : Integer) return Integer is (Param);
+
+  type Alpha_Typ is array (1 .. Get_Bound (1)) of Integer;
+  type Beta_Typ  is array (1 .. Get_Bound (0)) of Integer;
+
+  Alpha : Alpha_Typ;
+  Beta  : aliased Beta_Typ;
+
+begin
+  if Alpha'Address = Beta'Address then
+    raise Program_Error;
+  end if;
+end;