The attached testcase triggers an ICE during nested functions lowering, a 
regression present on the mainline and 4.6 branch.  The middle-end is trying 
to create an object which must be created by the front-end:

  /* If the type is of variable size or a type which must be created by the
     frontend, something is wrong.  Note that we explicitly allow
     incomplete types here, since we create them ourselves here.  */
  gcc_assert (!TREE_ADDRESSABLE (type));

This is a fallout of tuplification.  It turns out that the real issue was fixed 
back in July by Richard:

2010-07-07  Richard Guenther  <rguent...@suse.de>

        * tree-ssa-propagate.h (valid_gimple_call_p): Remove.
        * tree-ssa-propagate.c (valid_gimple_call_p): Make static.  Fix.
        * gimple.h (is_gimple_operand): Remove.
        * gimple.c (is_gimple_operand): Likewise.
        (walk_gimple_op): Fix wi->val_only setting for calls.
        * tree-cfg.c (verify_gimple_call): Fix argument validation.
        * tree-profile.c (tree_gen_ic_func_profiler): Do not create
        invalid gimple calls.

but the walk_gimple_op change contains a couple of oversights.

Bootstrapped/regtested on x86_64-suse-linux, applied on the mainline and 4.6 
branch as obvious.


2011-04-21  Eric Botcazou  <ebotca...@adacore.com>

        * gimple.c (walk_gimple_op) <GIMPLE_CALL>: Fix couple of oversights.


2011-04-21  Eric Botcazou  <ebotca...@adacore.com>

        * gnat.dg/volatile5.adb: New test.
        * gnat.dg/volatile5_pkg.ads: New helper.


-- 
Eric Botcazou
Index: gimple.c
===================================================================
--- gimple.c	(revision 172811)
+++ gimple.c	(working copy)
@@ -1464,7 +1464,8 @@ walk_gimple_op (gimple stmt, walk_tree_f
       for (i = 0; i < gimple_call_num_args (stmt); i++)
 	{
 	  if (wi)
-	    wi->val_only = is_gimple_reg_type (gimple_call_arg (stmt, i));
+	    wi->val_only
+	      = is_gimple_reg_type (TREE_TYPE (gimple_call_arg (stmt, i)));
 	  ret = walk_tree (gimple_call_arg_ptr (stmt, i), callback_op, wi,
 			   pset);
 	  if (ret)
@@ -1476,7 +1477,8 @@ walk_gimple_op (gimple stmt, walk_tree_f
 	  if (wi)
 	    {
 	      wi->is_lhs = true;
-	      wi->val_only = is_gimple_reg_type (gimple_call_lhs (stmt));
+	      wi->val_only
+		= is_gimple_reg_type (TREE_TYPE (gimple_call_lhs (stmt)));
 	    }
 
 	  ret = walk_tree (gimple_call_lhs_ptr (stmt), callback_op, wi, pset);
-- { dg-do compile }

with Volatile5_Pkg; use Volatile5_Pkg;

procedure Volatile5 is

   A : Rec;

   procedure Proc is
   begin
      A := F;
   end;

begin
   Proc;
end;
package Volatile5_Pkg is

   type Rec is record
      I : Integer;
   end record;
   pragma Volatile(Rec);

  function F return Rec;

end Volatile5_Pkg;
-- 

Reply via email to