aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorEd Schonberg <schonberg@adacore.com>2019-07-03 08:14:10 +0000
committerPierre-Marie de Rodat <pmderodat@gcc.gnu.org>2019-07-03 08:14:10 +0000
commit6cbd53c2277e5013d83fe73d5e73844066b651a7 (patch)
tree9aa66cca4c1bb2cb8381b52a6e9117171f792f01 /gcc
parent438d9658a90f7cf0fa06e219455629817fae4c65 (diff)
downloadgcc-6cbd53c2277e5013d83fe73d5e73844066b651a7.zip
gcc-6cbd53c2277e5013d83fe73d5e73844066b651a7.tar.gz
gcc-6cbd53c2277e5013d83fe73d5e73844066b651a7.tar.bz2
[Ada] Make loop labels unique for front-end inlined calls
This patch transforms loop labels in the body of subprograms that are to be inlined by the front-end, to prevent accidental duplication of loop labels, which might make the resulting source illegal. ---- Source program: ---- package P is procedure Get_Rom_Addr_Offset with Inline_Always; end P; ---- package body P is procedure Get_Rom_Addr_Offset is X : Integer; begin Main_Block : for I in 1 .. 10 loop X := 2; exit Main_Block when I > 4; other_loop: for J in character'('a') .. 'z' loop if I < 5 then exit Main_Block when J = 'k'; else Exit Other_Loop; end if; end loop other_loop; end loop Main_Block; end Get_Rom_Addr_Offset; procedure P2 is begin Main_Block : for I in 1 .. 1 loop Get_Rom_Addr_Offset; end loop Main_Block; end P2; end P; ---- Command: gcc -c -gnatN -gnatd.u -gnatDG p.adb ---- Output ---- package body p is procedure p__get_rom_addr_offset is x : integer; other_loop : label main_block : label begin main_block : for i in 1 .. 10 loop x := 2; exit main_block when i > 4; other_loop : for j in 'a' .. 'z' loop if i < 5 then exit main_block when j = 'k'; else exit other_loop; end if; end loop other_loop; end loop main_block; return; end p__get_rom_addr_offset; procedure p__p2 is main_block : label begin main_block : for i in 1 .. 1 loop B6b : declare x : integer; other_loopL10b : label main_blockL9b : label begin main_blockL9b : for i in 1 .. 10 loop x := 2; exit main_blockL9b when i > 4; other_loopL10b : for j in 'a' .. 'z' loop if i < 5 then exit main_blockL9b when j = 'k'; else exit other_loopL10b; end if; end loop other_loopL10b; end loop main_blockL9b; end B6b; end loop main_block; return; end p__p2; begin null; end p; 2019-07-03 Ed Schonberg <schonberg@adacore.com> gcc/ada/ * inline.adb (Make_Loop_Labels_Unique): New procedure to modify the source code of subprograms that are inlined by the front-end, to prevent accidental duplication between loop labels in the inlined code and the code surrounding the inlined call. From-SVN: r272967
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ada/ChangeLog7
-rw-r--r--gcc/ada/inline.adb62
2 files changed, 69 insertions, 0 deletions
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index 2115a38..443947c 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,3 +1,10 @@
+2019-07-03 Ed Schonberg <schonberg@adacore.com>
+
+ * inline.adb (Make_Loop_Labels_Unique): New procedure to modify
+ the source code of subprograms that are inlined by the
+ front-end, to prevent accidental duplication between loop labels
+ in the inlined code and the code surrounding the inlined call.
+
2019-07-03 Hristian Kirtchev <kirtchev@adacore.com>
* doc/gnat_ugn/elaboration_order_handling_in_gnat.rst: Update
diff --git a/gcc/ada/inline.adb b/gcc/ada/inline.adb
index 709513d..ae1c217 100644
--- a/gcc/ada/inline.adb
+++ b/gcc/ada/inline.adb
@@ -2381,6 +2381,11 @@ package body Inline is
-- When generating C code, declare _Result, which may be used in the
-- inlined _Postconditions procedure to verify the return value.
+ procedure Make_Loop_Labels_Unique (Stats : Node_Id);
+ -- When compiling for CCG and performing front-end inlining, replace
+ -- loop names and references to them so that they do not conflict
+ -- with homographs in the current subprogram.
+
procedure Make_Exit_Label;
-- Build declaration for exit label to be used in Return statements,
-- sets Exit_Lab (the label node) and Lab_Decl (corresponding implicit
@@ -2474,6 +2479,59 @@ package body Inline is
end if;
end Make_Exit_Label;
+ -----------------------------
+ -- Make_Loop_Labels_Unique --
+ -----------------------------
+
+ procedure Make_Loop_Labels_Unique (Stats : Node_Id) is
+ S : Node_Id;
+
+ function Process_Loop (N : Node_Id) return Traverse_Result;
+
+ ------------------
+ -- Process_Loop --
+ ------------------
+
+ function Process_Loop (N : Node_Id) return Traverse_Result is
+ Id : Entity_Id;
+
+ begin
+ if Nkind (N) = N_Loop_Statement
+ and then Present (Identifier (N))
+ then
+
+ -- Create new external name for loop. and update the
+ -- corresponding entity.
+
+ Id := Entity (Identifier (N));
+ Set_Chars (Id, New_External_Name (Chars (Id), 'L', -1));
+ Set_Chars (Identifier (N), Chars (Id));
+
+ elsif Nkind (N) = N_Exit_Statement
+ and then Present (Name (N))
+ then
+
+ -- The exit statement must name an enclosing loop, whose
+ -- name has already been updated.
+
+ Set_Chars (Name (N), Chars (Entity (Name (N))));
+ end if;
+
+ return OK;
+ end Process_Loop;
+
+ procedure Update_Loop_Names is new Traverse_Proc (Process_Loop);
+
+ begin
+ if Modify_Tree_For_C then
+ S := First (Statements (Stats));
+ while Present (S) loop
+ Update_Loop_Names (S);
+ Next (S);
+ end loop;
+ end if;
+ end Make_Loop_Labels_Unique;
+
---------------------
-- Process_Formals --
---------------------
@@ -2742,6 +2800,8 @@ package body Inline is
Fst : constant Node_Id := First (Statements (HSS));
begin
+ Make_Loop_Labels_Unique (HSS);
+
-- Optimize simple case: function body is a single return statement,
-- which has been expanded into an assignment.
@@ -2829,6 +2889,8 @@ package body Inline is
HSS : constant Node_Id := Handled_Statement_Sequence (Blk);
begin
+ Make_Loop_Labels_Unique (HSS);
+
-- If there is a transient scope for N, this will be the scope of the
-- actions for N, and the statements in Blk need to be within this
-- scope. For example, they need to have visibility on the constant