[Ada] If-expressions and the capture of local values
Arnaud Charlet
charlet@adacore.com
Thu Apr 11 12:54:00 GMT 2013
The routine Safe_To_Capture_Values performs simple data-flow to determine
whether some characteristic of a variable (its value after assignment, or the
fact that an access value is non-null after a test) can be used downstream.
The value cannot be saved if the expression that determines that value appears
within a conditional construct. This patch recognizes the case where the
expression appears within the else_actions of a if_expression. In that case,
before the if-expression is expanded, those actions are not directly attached
to the AST.
Executing:
gnatmake -q -gnatwa -gnat12 test_null1.adb
test_null1
must yield:
AAA
---
pragma Ada_2012;
with Text_IO; use Text_IO;
procedure Test_Null1 is
type String_Access is access all String;
type String_List is array (Positive range <>) of String_Access;
type String_List_Access is access all String_List;
procedure Dump (L : String_List_Access) is
begin
if L /= null then
for J in L'Range loop
Put_Line (L (J).all);
end loop;
end if;
end Dump;
procedure Append
(L : in out String_List_Access;
S : String);
procedure Append
(L : in out String_List_Access;
S : String)
is
Tmp : constant String_List_Access :=
(if L = null then
new String_List (1 .. 1)
else
new String_List (1 .. L'Length + 1));
Idx : Positive := 1;
begin
if L /= null then
for J in L'Range loop
Tmp (Idx) := new String'(L (J).all);
Idx := Idx + 1;
end loop;
end if;
Tmp (Idx) := new String'(S);
L := Tmp;
end Append;
L : String_List_Access := null;
begin
Append (L, "AAA");
Dump (L);
end Test_Null1;
Tested on x86_64-pc-linux-gnu, committed on trunk
2013-04-11 Ed Schonberg <schonberg@adacore.com>
* sem_util.adb (Safe_To_Capture_Value): If the node belongs to
an expression that has been attached to the else_actions of an
if-expression, the capture is not safe.
-------------- next part --------------
Index: sem_util.adb
===================================================================
--- sem_util.adb (revision 197744)
+++ sem_util.adb (working copy)
@@ -12984,6 +12984,19 @@
else
Desc := P;
P := Parent (P);
+
+ -- A special Ada 2012 case: the original node may be part
+ -- of the else_actions of a conditional expression, in which
+ -- case it might not have been expanded yet, and appears in
+ -- a non-syntactic list of actions. In that case it is clearly
+ -- not safe to save a value.
+
+ if No (P)
+ and then Is_List_Member (Desc)
+ and then No (Parent (List_Containing (Desc)))
+ then
+ return False;
+ end if;
end if;
end loop;
end;
More information about the Gcc-patches
mailing list