2015-12-02 Pierre-Marie de Rodat * dwarf2out.c (dwar2out_var_location): Enhance pattern matching to get the SYMBOL_REF they embed. (gen_subprogram_die): Handle such calls. --- gcc/dwarf2out.c (revision 231184) +++ gcc/dwarf2out.c (revision 231185) @@ -18051,18 +18051,23 @@ gen_subprogram_die (tree decl, dw_die_re } if (mode == VOIDmode || mode == BLKmode) continue; - if (XEXP (XEXP (arg, 0), 0) == pc_rtx) + /* Get dynamic information about call target only if we + have no static information: we cannot generate both + DW_AT_abstract_origin and DW_AT_GNU_call_site_target + attributes. */ + if (ca_loc->symbol_ref == NULL_RTX) { - gcc_assert (ca_loc->symbol_ref == NULL_RTX); - tloc = XEXP (XEXP (arg, 0), 1); - continue; - } - else if (GET_CODE (XEXP (XEXP (arg, 0), 0)) == CLOBBER - && XEXP (XEXP (XEXP (arg, 0), 0), 0) == pc_rtx) - { - gcc_assert (ca_loc->symbol_ref == NULL_RTX); - tlocc = XEXP (XEXP (arg, 0), 1); - continue; + if (XEXP (XEXP (arg, 0), 0) == pc_rtx) + { + tloc = XEXP (XEXP (arg, 0), 1); + continue; + } + else if (GET_CODE (XEXP (XEXP (arg, 0), 0)) == CLOBBER + && XEXP (XEXP (XEXP (arg, 0), 0), 0) == pc_rtx) + { + tlocc = XEXP (XEXP (arg, 0), 1); + continue; + } } reg = NULL; if (REG_P (XEXP (XEXP (arg, 0), 0))) @@ -20842,15 +20847,27 @@ dwarf2out_var_location (rtx loc_note) if (!CALL_P (prev)) prev = XVECEXP (PATTERN (prev), 0, 0); ca_loc->tail_call_p = SIBLING_CALL_P (prev); + + /* Look for a SYMBOL_REF in the "prev" instruction. */ x = get_call_rtx_from (PATTERN (prev)); if (x) { - x = XEXP (XEXP (x, 0), 0); - if (GET_CODE (x) == SYMBOL_REF - && SYMBOL_REF_DECL (x) - && TREE_CODE (SYMBOL_REF_DECL (x)) == FUNCTION_DECL) - ca_loc->symbol_ref = x; + /* Try to get the call symbol, if any. */ + if (MEM_P (XEXP (x, 0))) + x = XEXP (x, 0); + /* First, look for a memory access to a symbol_ref. */ + if (GET_CODE (XEXP (x, 0)) == SYMBOL_REF + && SYMBOL_REF_DECL (XEXP (x, 0)) + && TREE_CODE (SYMBOL_REF_DECL (XEXP (x, 0))) == FUNCTION_DECL) + ca_loc->symbol_ref = XEXP (x, 0); + /* Otherwise, look at a compile-time known user-level function + declaration. */ + else if (MEM_P (x) + && MEM_EXPR (x) + && TREE_CODE (MEM_EXPR (x)) == FUNCTION_DECL) + ca_loc->symbol_ref = XEXP (DECL_RTL (MEM_EXPR (x)), 0); } + ca_loc->block = insn_scope (prev); if (call_arg_locations) call_arg_loc_last->next = ca_loc;