------- Comment #12 from rguenth at gcc dot gnu dot org 2010-08-07 21:16 ------- Ok, I see when gimplifying the call that we mark it for NRV because while x doesn't have it's address taken it's value-expr has and we didn't replace it at that point but we check
4262 else if (!is_gimple_non_addressable (*to_p)) 4271 use_target = true; so I think this is a bug that it doesn't mark the original parameter decl as address-taken which happens here (function.c:gimplify_parameters): /* If PARM was addressable, move that flag over to the local copy, as its address will be taken, not the PARMs. */ if (TREE_ADDRESSABLE (parm)) { TREE_ADDRESSABLE (parm) = 0; TREE_ADDRESSABLE (local) = 1; } We should defer clearing the param addressable flag to update_address_taken. So the following should fix this. Can you bootstrap/test this? Index: gcc/function.c =================================================================== --- gcc/function.c (revision 162781) +++ gcc/function.c (working copy) @@ -3423,12 +3423,10 @@ gimplify_parameters (void) DECL_IGNORED_P (local) = 0; /* If PARM was addressable, move that flag over to the local copy, as its address will be taken, - not the PARMs. */ + not the PARMs. Keep the parms address taken + as we'll query that flag during gimplification. */ if (TREE_ADDRESSABLE (parm)) - { - TREE_ADDRESSABLE (parm) = 0; - TREE_ADDRESSABLE (local) = 1; - } + TREE_ADDRESSABLE (local) = 1; } else { (patch to the 4.5 branch, but should apply to the trunk as well). -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=44632