diff options
author | Eric Botcazou <ebotcazou@adacore.com> | 2019-09-18 08:33:12 +0000 |
---|---|---|
committer | Pierre-Marie de Rodat <pmderodat@gcc.gnu.org> | 2019-09-18 08:33:12 +0000 |
commit | 6951cbc9e7646bca1c99c973815e6838a6e1fe25 (patch) | |
tree | 8dfe7973960559f51dccdec8f4e2cb72721875f7 /gcc/testsuite | |
parent | 43b264110f5581af0cc93308f9433fe8053f01cc (diff) | |
download | gcc-6951cbc9e7646bca1c99c973815e6838a6e1fe25.zip gcc-6951cbc9e7646bca1c99c973815e6838a6e1fe25.tar.gz gcc-6951cbc9e7646bca1c99c973815e6838a6e1fe25.tar.bz2 |
[Ada] Fix sharing of expression in array aggregate with others choice
This change fixes a long-standing issue in the compiler that is
generally silent but may lead to wrong code generation in specific
circumstances. When an others choice in an array aggregate spans
multiple ranges, the compiler may generate multiple (groups of)
assignments for the ranges.
The problem is that it internally reuses the original expression for all
the ranges, which is problematic if this expression gets rewritten
during the processing of one of the ranges and typically causes a new
temporary to be shared between different ranges.
The solution is to duplicate the original expression for each range.
2019-09-18 Eric Botcazou <ebotcazou@adacore.com>
gcc/ada/
* exp_aggr.adb (Build_Array_Aggr_Code): In STEP 1 (c), duplicate
the expression and reset the Loop_Actions for each loop
generated for an others choice.
gcc/testsuite/
* gnat.dg/aggr28.adb: New testcase.
From-SVN: r275859
Diffstat (limited to 'gcc/testsuite')
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gnat.dg/aggr28.adb | 29 |
2 files changed, 33 insertions, 0 deletions
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index fd0efb1..32297d1 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2019-09-18 Eric Botcazou <ebotcazou@adacore.com> + + * gnat.dg/aggr28.adb: New testcase. + 2019-09-18 Steve Baird <baird@adacore.com> * gnat.dg/ai12_0086_example.adb: New testcase. diff --git a/gcc/testsuite/gnat.dg/aggr28.adb b/gcc/testsuite/gnat.dg/aggr28.adb new file mode 100644 index 0000000..3375b71 --- /dev/null +++ b/gcc/testsuite/gnat.dg/aggr28.adb @@ -0,0 +1,29 @@ +-- { dg-do run } + +procedure Aggr28 is + + Count : Natural := 0; + + function Get (S: String) return String is + begin + Count := Count + 1; + return S; + end; + + Max_Error_Length : constant := 8; + subtype Error_Type is String (1 .. Max_Error_Length); + + type Rec is record + Text : Error_Type; + end record; + + type Arr is array (1 .. 16) of Rec; + + Table : constant Arr := + (3 => (Text => Get ("INVALID ")), others => (Text => Get ("OTHERS "))); + +begin + if Count /= Table'Length then + raise Program_Error; + end if; +end;
\ No newline at end of file |