Hi! If a PARM_DECL is not passed by reference because the FE decides so (then the PARM_DECL is DECL_BY_REFERENCE and has pointer type), but because pass_by_reference said so, then apparently DECL_INCOMING is the Pmode pointer to the MEM instead of the actual incoming location and the fact that expansion decided that isn't stored anywhere. While we could in theory reconstruct that by doing all the INIT_CUMULATIVE_ARGS/*function_arg{,_advance}/pass_by_reference etc., that is fairly costly to do and just guessing whether it is the case isn't reliable.
One place where we want to know that is in expand_debug_expr since my recent change to add ENTRY_VALUE if debug stmts reference a parameter that isn't used in the function at all. But the debug info emitters want to know that too, and DECL_INCOMING_RTL seems to be there just for them. I was considering adding some DECL_INCOMING_BY_REFERENCE bit to PARM_DECL, but I think it is actually better if DECL_INCOMING_RTL in that case is just a MEM of the right mode with the register (or stack slot MEM) as address. This patch fixes both the problem of e.g. complex-1.c on cris-elf where expand_debug_expr was upset that DECL_INCOMING_RTL was SImode, but the argument was supposed to be DFmode, and also e.g. improves debug info for -g -m32 -O+ on powerpc-linux: struct S { char buf[16]; }; void foo (struct S a, int b, int c, int d, int e, int f, int g, int h, struct S i) { } without the patch there is no location info for A and I parameters, with this patch the location info is present and correct. Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2011-03-17 Jakub Jelinek <ja...@redhat.com> PR debug/48163 * function.c (assign_parms): For data.passed_pointer parms use MEM of data.entry_parm instead of data.entry_parm itself as DECL_INCOMING_RTL. * dwarf2out.c (rtl_for_decl_location): Use DECL_INCOMING_RTL also when passed and declared mode is the same, DECL_RTL is a MEM with pseudo as address and DECL_INCOMING_RTL is a MEM too. --- gcc/function.c.jj 2011-03-11 12:16:39.000000000 +0100 +++ gcc/function.c 2011-03-17 11:44:41.000000000 +0100 @@ -3403,7 +3403,15 @@ assign_parms (tree fndecl) } /* Record permanently how this parm was passed. */ - set_decl_incoming_rtl (parm, data.entry_parm, data.passed_pointer); + if (data.passed_pointer) + { + rtx incoming_rtl + = gen_rtx_MEM (TYPE_MODE (TREE_TYPE (data.passed_type)), + data.entry_parm); + set_decl_incoming_rtl (parm, incoming_rtl, true); + } + else + set_decl_incoming_rtl (parm, data.entry_parm, false); /* Update info on where next arg arrives in registers. */ targetm.calls.function_arg_advance (&all.args_so_far, data.promoted_mode, --- gcc/dwarf2out.c.jj 2011-03-17 09:38:00.000000000 +0100 +++ gcc/dwarf2out.c 2011-03-17 12:07:01.000000000 +0100 @@ -16719,7 +16719,13 @@ rtl_for_decl_location (tree decl) } else if (TREE_CODE (decl) == PARM_DECL) { - if (rtl == NULL_RTX || is_pseudo_reg (rtl)) + if (rtl == NULL_RTX + || is_pseudo_reg (rtl) + || (MEM_P (rtl) + && is_pseudo_reg (XEXP (rtl, 0)) + && DECL_INCOMING_RTL (decl) + && MEM_P (DECL_INCOMING_RTL (decl)) + && GET_MODE (rtl) == GET_MODE (DECL_INCOMING_RTL (decl)))) { tree declared_type = TREE_TYPE (decl); tree passed_type = DECL_ARG_TYPE (decl); @@ -16731,7 +16737,8 @@ rtl_for_decl_location (tree decl) all cases where (rtl == NULL_RTX) just below. */ if (dmode == pmode) rtl = DECL_INCOMING_RTL (decl); - else if (SCALAR_INT_MODE_P (dmode) + else if ((rtl == NULL_RTX || is_pseudo_reg (rtl)) + && SCALAR_INT_MODE_P (dmode) && GET_MODE_SIZE (dmode) <= GET_MODE_SIZE (pmode) && DECL_INCOMING_RTL (decl)) { Jakub