[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