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; --