diff options
author | Eric Botcazou <ebotcazou@adacore.com> | 2022-12-07 00:56:43 +0100 |
---|---|---|
committer | Marc Poulhiès <poulhies@adacore.com> | 2023-01-03 10:29:53 +0100 |
commit | 7caa68418199bf2116467780d68ba21d49c45cdb (patch) | |
tree | cbf01c8d5ab9af464d90543a754051d2b499397c | |
parent | 7512dcc94236d247ceef8cef6d36392a86e271a0 (diff) | |
download | gcc-7caa68418199bf2116467780d68ba21d49c45cdb.zip gcc-7caa68418199bf2116467780d68ba21d49c45cdb.tar.gz gcc-7caa68418199bf2116467780d68ba21d49c45cdb.tar.bz2 |
ada: Fix detection of function calls in object declarations
The current code has relied on Original_Node to detect rewritten function
calls in object declarations but that's not robust enough in the presence
of function calls written in object notation.
gcc/ada/
* exp_util.ads (Is_Captured_Function_Call): Declare.
* exp_util.adb (Is_Captured_Function_Call): New predicate.
* exp_ch3.adb (Expand_N_Object_Declaration): Use it to detect a
rewritten function call as the initializing expression.
* exp_ch6.adb (Expand_Simple_Function_Return): Use it to detect a
rewritten function call as the returned expression.
-rw-r--r-- | gcc/ada/exp_ch3.adb | 10 | ||||
-rw-r--r-- | gcc/ada/exp_ch6.adb | 6 | ||||
-rw-r--r-- | gcc/ada/exp_util.adb | 24 | ||||
-rw-r--r-- | gcc/ada/exp_util.ads | 8 |
4 files changed, 37 insertions, 11 deletions
diff --git a/gcc/ada/exp_ch3.adb b/gcc/ada/exp_ch3.adb index 6de5843..def63ed 100644 --- a/gcc/ada/exp_ch3.adb +++ b/gcc/ada/exp_ch3.adb @@ -7901,18 +7901,16 @@ package body Exp_Ch3 is -- secondary stack, then the declaration can be rewritten as -- the renaming of this dereference: - -- type Axx is access all Typ; - -- Rxx : constant Axx := Func (...)'reference; - -- Obj : Typ renames Rxx.all; + -- type Ann is access all Typ; + -- Rnn : constant Axx := Func (...)'reference; + -- Obj : Typ renames Rnn.all; -- This avoids an extra copy and, in the case where Typ needs -- finalization, a pair of Adjust/Finalize calls (see below). and then ((not Is_Library_Level_Entity (Def_Id) - and then Nkind (Expr_Q) = N_Explicit_Dereference - and then not Comes_From_Source (Expr_Q) - and then Nkind (Original_Node (Expr_Q)) = N_Function_Call + and then Is_Captured_Function_Call (Expr_Q) and then not Is_Class_Wide_Type (Typ)) -- If the initializing expression is a variable with the diff --git a/gcc/ada/exp_ch6.adb b/gcc/ada/exp_ch6.adb index c026b63..0bc2559 100644 --- a/gcc/ada/exp_ch6.adb +++ b/gcc/ada/exp_ch6.adb @@ -6440,11 +6440,7 @@ package body Exp_Ch6 is pragma Assert (Present (Exp)); Exp_Is_Function_Call : constant Boolean := - Nkind (Exp) = N_Function_Call - or else (Nkind (Exp) = N_Explicit_Dereference - and then Is_Entity_Name (Prefix (Exp)) - and then Ekind (Entity (Prefix (Exp))) = E_Constant - and then Is_Related_To_Func_Return (Entity (Prefix (Exp)))); + Nkind (Exp) = N_Function_Call or else Is_Captured_Function_Call (Exp); Exp_Typ : constant Entity_Id := Etype (Exp); -- The type of the expression (not necessarily the same as R_Type) diff --git a/gcc/ada/exp_util.adb b/gcc/ada/exp_util.adb index 5ab0d30..3c68f91 100644 --- a/gcc/ada/exp_util.adb +++ b/gcc/ada/exp_util.adb @@ -8160,6 +8160,30 @@ package body Exp_Util is end if; end Integer_Type_For; + ------------------------------- + -- Is_Captured_Function_Call -- + ------------------------------- + + function Is_Captured_Function_Call (N : Node_Id) return Boolean is + begin + if Nkind (N) = N_Explicit_Dereference + and then Is_Entity_Name (Prefix (N)) + and then Ekind (Entity (Prefix (N))) = E_Constant + then + declare + Value : constant Node_Id := Constant_Value (Entity (Prefix (N))); + + begin + return Present (Value) + and then Nkind (Value) = N_Reference + and then Nkind (Prefix (Value)) = N_Function_Call; + end; + + else + return False; + end if; + end Is_Captured_Function_Call; + -------------------------------------------------- -- Is_Displacement_Of_Object_Or_Function_Result -- -------------------------------------------------- diff --git a/gcc/ada/exp_util.ads b/gcc/ada/exp_util.ads index a21fb8b..0d09d25 100644 --- a/gcc/ada/exp_util.ads +++ b/gcc/ada/exp_util.ads @@ -757,6 +757,14 @@ package Exp_Util is -- Return a suitable standard integer type containing at least S bits and -- of the signedness given by Uns. See also Small_Integer_Type_For. + function Is_Captured_Function_Call (N : Node_Id) return Boolean; + -- Return True if N is a captured function call, i.e. the result of calling + -- Remove_Side_Effects on an N_Function_Call node: + + -- type Ann is access all Typ; + -- Rnn : constant Ann := Func (...)'reference; + -- Rnn.all + function Is_Displacement_Of_Object_Or_Function_Result (Obj_Id : Entity_Id) return Boolean; -- Determine whether Obj_Id is a source entity that has been initialized by |