[Ada] Wrong value after assignment of overlain record objects
authorJustin Squirek <squirek@adacore.com>
Tue, 31 Jul 2018 09:56:04 +0000 (09:56 +0000)
committerPierre-Marie de Rodat <pmderodat@gcc.gnu.org>
Tue, 31 Jul 2018 09:56:04 +0000 (09:56 +0000)
This patch corrects an issue whereby objects of a record type with a
representation clause which are overlain by address would fail to get
assigned values properly when one or both of said objects were marked
volatile.

2018-07-31  Justin Squirek  <squirek@adacore.com>

gcc/ada/

* exp_ch5.adb (Make_Field_Assign): Force temporarily generated
objects for assignment of overlaid user objects to be renamings
instead of constant declarations.

gcc/testsuite/

* gnat.dg/addr11.adb: New testcase.

From-SVN: r263098

gcc/ada/ChangeLog
gcc/ada/exp_ch5.adb
gcc/testsuite/ChangeLog
gcc/testsuite/gnat.dg/addr11.adb [new file with mode: 0644]

index 08fdfcebfcadbdae9dd3d62f0850add0bdef28c0..0d26bb50fdadaeb0acde5175863c4ff7a6c10e69 100644 (file)
@@ -1,3 +1,9 @@
+2018-07-31  Justin Squirek  <squirek@adacore.com>
+
+       * exp_ch5.adb (Make_Field_Assign): Force temporarily generated
+       objects for assignment of overlaid user objects to be renamings
+       instead of constant declarations.
+
 2018-07-31  Hristian Kirtchev  <kirtchev@adacore.com>
 
        * exp_ch9.adb (Analyze_Pragmas): New routine.
index f2a26685dae237e13a1ac1b4bd5aad3b8b6e5fd3..7a373ab883bc6b46d451a0bf752a494189b1492b 100644 (file)
@@ -1531,11 +1531,22 @@ package body Exp_Ch5 is
                    Selector_Name => New_Occurrence_Of (Disc, Loc));
             end if;
 
+            --  Generate the assignment statement. When the left-hand side
+            --  is an object with an address clause present, force generated
+            --  temporaries to be renamings so as to correctly assign to any
+            --  overlaid objects.
+
             A :=
               Make_Assignment_Statement (Loc,
                 Name       =>
                   Make_Selected_Component (Loc,
-                    Prefix        => Duplicate_Subexpr (Lhs),
+                    Prefix        =>
+                      Duplicate_Subexpr
+                        (Exp          => Lhs,
+                         Name_Req     => False,
+                         Renaming_Req =>
+                           Is_Entity_Name (Lhs)
+                             and then Present (Address_Clause (Entity (Lhs)))),
                     Selector_Name =>
                       New_Occurrence_Of (Find_Component (L_Typ, C), Loc)),
                 Expression => Expr);
index 00cf622343e8ec9d5ce9f5cd1c0217a612a8e500..d7b99081f0dd09f47f14b085bfabd4334b2d7484 100644 (file)
@@ -1,3 +1,7 @@
+2018-07-31  Justin Squirek  <squirek@adacore.com>
+
+       * gnat.dg/addr11.adb: New testcase.
+
 2018-07-31  Hristian Kirtchev  <kirtchev@adacore.com>
 
        * gnat.dg/global.adb, gnat.dg/global.ads: New testcase.
diff --git a/gcc/testsuite/gnat.dg/addr11.adb b/gcc/testsuite/gnat.dg/addr11.adb
new file mode 100644 (file)
index 0000000..c705399
--- /dev/null
@@ -0,0 +1,28 @@
+--  { dg-do run }
+
+procedure Addr11 is
+
+  type Rec is record
+    I : Short_Integer;
+    C : Character;
+  end record;
+
+  type Derived is new Rec;
+  for Derived use record
+    I at 1 range 0 .. 15;
+    C at 0 range 0 .. 7;
+  end record;
+
+  Init : constant Rec := ( 1515, 'A' );
+
+  D1 : Derived;
+  D2 : Derived;
+  pragma Volatile (D2);
+  for D2'Address use D1'Address;
+
+begin
+  D2 := Derived (Init);
+  if D1 /= Derived (Init) then
+    raise Program_Error;
+  end if;
+end;