[patch] honor DECL_BY_REFERENCE on CALL_EXPR exp in aggregate_value_p
Olivier Hainque
hainque@adacore.com
Sat Jun 24 16:16:00 GMT 2006
Hello,
With the GCC 3.4 series, a front-end requesting a function to return
by invisible reference used to merely have to set TREE_ADDRESSABLE on
the proper types.
Current mainline now expects everything to be exposed explicitely, as
illustrated by cp_genericize for C++, for instance. Amongst other things,
the function result decl is marked DECL_BY_REFERENCE and the associated
type is made an explicit reference type.
The Ada front-end has not gone through this transition yet and relies on the
gimplifier for temporary creations in a number of circumstances.
One kind of observable effect is ICEs from attempts at creating temporaries of
TREE_ADDRESSABLE type, e.g. while compiling check_result_by_ref.adb in the
testcase below.
We are working at resolving this issue. Part of our current scheme consists
in unsetting the TREE_ADDRESSABLE flag on the function type, which prevents
part of the middle-end magic to work - in particular, the following bits from
expand_call:
/* Set up a place to return a structure. */
...
if (aggregate_value_p (exp, fndecl))
The attached patch is a simple helper for the aforementioned expand_call
issue, preriquisite for a larger change to come, hence part of a regression
fix.
Bootstrapped and successfully regression tested with languages=all,ada
on i686-pc-linux-gnu.
2006-06-24 Olivier Hainque <hainque@adacore.com>
* function.c (aggregate_value_p): Honor DECL_BY_REFERENCE on
a CALL_EXPR target function declaration.
Thanks in advance.
Olivier
--
Testcase:
-- result_by_ref.ads
package Result_By_Ref is
type Point is record
X, Y, Z : Integer;
end record;
function Ref_Loc return Point;
pragma Export_Function
(Ref_Loc, External => "Loc", Result_Mechanism => Reference);
Ref_Point : Point := (0, 0, 0);
end;
-- result_by_ref.adb
package body Result_By_Ref is
function Ref_Loc return Point is
begin
return Ref_Point;
end;
end;
-- check_result_by_ref.adb
with Result_By_Ref; use Result_By_Ref;
procedure Check_Result_By_Ref is
L : Point := Ref_Loc;
begin
if L /= Ref_Point then
raise Program_Error;
end if;
end;
--
-------------- next part --------------
*** function.c.ori Fri Jun 9 11:13:45 2006
--- function.c Tue Jun 13 16:42:43 2006
*************** aggregate_value_p (tree exp, tree fntype
*** 1751,1765 ****
tree type = (TYPE_P (exp)) ? exp : TREE_TYPE (exp);
if (fntype)
switch (TREE_CODE (fntype))
{
case CALL_EXPR:
! fntype = get_callee_fndecl (fntype);
! fntype = fntype ? TREE_TYPE (fntype) : 0;
break;
case FUNCTION_DECL:
! fntype = TREE_TYPE (fntype);
break;
case FUNCTION_TYPE:
case METHOD_TYPE:
--- 1751,1768 ----
tree type = (TYPE_P (exp)) ? exp : TREE_TYPE (exp);
+ tree fndecl = NULL_TREE;
+
if (fntype)
switch (TREE_CODE (fntype))
{
case CALL_EXPR:
! fndecl = get_callee_fndecl (fntype);
! fntype = fndecl ? TREE_TYPE (fndecl) : 0;
break;
case FUNCTION_DECL:
! fndecl = fntype;
! fntype = TREE_TYPE (fndecl);
break;
case FUNCTION_TYPE:
case METHOD_TYPE:
*************** aggregate_value_p (tree exp, tree fntype
*** 1779,1784 ****
--- 1782,1791 ----
if ((TREE_CODE (exp) == PARM_DECL || TREE_CODE (exp) == RESULT_DECL)
&& DECL_BY_REFERENCE (exp))
return 1;
+ if (TREE_CODE (exp) == CALL_EXPR && fndecl && DECL_RESULT (fndecl)
+ && DECL_BY_REFERENCE (DECL_RESULT (fndecl)))
+ return 1;
+
if (targetm.calls.return_in_memory (type, fntype))
return 1;
/* Types that are TREE_ADDRESSABLE must be constructed in memory,
More information about the Gcc-patches
mailing list