Hi, In GCC 4.7.2 in function.c, inside assign_parm_find_data_types there is distinction between passed and nominal mode.
nominal_type = TREE_TYPE (parm); passed_type = DECL_ARG_TYPE (parm); Next data->passed_pointer is set to true if passed_type should pass by reference. Consider synthetic code: double g (); typedef union { struct { unsigned s:1, e:8, f:23; } u; float f; } s; f(x, n) float x; { ((s *)&x)->u.e -= n; x = g((double)x, -n); } In this case, for argument x, nominal_type is <real_type float> and passed_type is <real_type double>. Now suppose some private backend, where single floats are passed in registers and doubles in memory. In this case data->passed_pointer will be set to true. But really it is passed in memory. So next inside assign_parms, DECL_RTL field will be set to register, and later inside expand_expr_addr_expr_1, this will assert on gcc_assert (MEM_P (result)); Just rewriting f as: f(float x, int n) { ((s *)&x)->u.e -= n; x = g((double)x, -n); } corrects things -- now both nominal_type and passed_type are float. But I really want to be able to compile old-style definitions also. So question is -- why assign_parm_find_data_types prefers passed_type to nominal_type in checking if things are passing by reference, and what is preferable way to fix this case? Maybe there already exists some bug? I can not reproduce this case on any existing backend, it seems x86 and arm passes SF and DF uniformly, so I am writing here, not in bugzilla. --- With best regards, Konstantin