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.
Tested on x86_64-pc-linux-gnu, committed on trunk
2018-07-31 Justin Squirek <squi...@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.
--- gcc/ada/exp_ch5.adb
+++ gcc/ada/exp_ch5.adb
@@ -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);
--- /dev/null
new file mode 100644
+++ gcc/testsuite/gnat.dg/addr11.adb
@@ -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;