------- Comment #11 from davek at gcc dot gnu dot org  2009-09-15 14:53 -------
The bogus const info is added in at the end of this call chain, when generating
the var die:

#0  0x004d0679 in add_const_value_attribute (die=0x7fcbd660, rtl=0x7fd20270)
    at /gnu/gcc/gcc/gcc/tree.h:182
#1  0x004d25ec in add_location_or_const_value_attribute (die=0x7fcbd660, 
    decl=0x7fe19e40, attr=DW_AT_location) at /gnu/gcc/gcc/gcc/tree.h:182
#2  0x004da1f2 in gen_variable_die (decl=0x7fe19e40, origin=0x0, 
    context_die=0x7fcbbe50) at /gnu/gcc/gcc/gcc/tree.h:182
#3  0x004deda3 in gen_decl_die (decl=0x7fe19e40, origin=0x0, 
    context_die=0x7fcbbe50) at /gnu/gcc/gcc/gcc/tree.h:182
#4  0x004dd3ed in process_scope_var (stmt=0x7fcb2060, decl=0x7fe19e40, 
    origin=0x0, context_die=0x7fcbbe50) at /gnu/gcc/gcc/gcc/tree.h:182
#5  0x004dd470 in decls_for_scope (stmt=0x7fcb2060, context_die=0x7fcbbe50, 
    depth=0) at /gnu/gcc/gcc/gcc/tree.h:182
#6  0x004d91d8 in gen_subprogram_die (decl=0x7fdfb500, context_die=0x7fe03678)
    at /gnu/gcc/gcc/gcc/tree.h:182
#7  0x004dea1c in gen_decl_die (decl=0x7fdfb500, origin=0x0, 
    context_die=0x7fe03678) at /gnu/gcc/gcc/gcc/tree.h:182
#8  0x004dfb56 in dwarf2out_decl (decl=0x7fdfb500)
    at /gnu/gcc/gcc/gcc/tree.h:182
#9  0x00834dbf in rest_of_handle_final () at /gnu/gcc/gcc/gcc/final.c:3131

In the above call stack, the rtx that is passed to add_const_value_attribute()
looks like this:

(gdb) call debug_rtx (rtl)
(symbol_ref:SI ("gomp_tls_data") [flags 0x42] <var_decl 0x7fe190c0
gomp_tls_data
>)

There is code in add_const_value_attribute() to avoid this problem already:

 12789  /* Attach a DW_AT_const_value attribute for a variable or a parameter
which
 12790     does not have a "location" either in memory or in a register.  These
 12791     things can arise in GNU C when a constant is passed as an actual
parameter
 12792     to an inlined function.  They can also arise in C++ where declared
 12793     constants do not necessarily get memory "homes".  */
 12794  
 12795  static void
 12796  add_const_value_attribute (dw_die_ref die, rtx rtl)
 12797  {
 12798    switch (GET_CODE (rtl))
 12799      {
     [ ... ]
 12911      case SYMBOL_REF:
 12912        if (GET_CODE (rtl) == SYMBOL_REF
 12913            && SYMBOL_REF_TLS_MODEL (rtl) != TLS_MODEL_NONE)
 12914          break;
 12915      case LABEL_REF:
 12916        add_AT_addr (die, DW_AT_const_value, rtl);
 12917        VEC_safe_push (rtx, gc, used_rtx_array, rtl);
 12918        break;

and indeed, it works by simply punting if the symbol ref in question points to
a TLS item, but the flags are wrong in the rtx that is passed in:

(symbol_ref:SI ("gomp_tls_data") [flags 0x42] <var_decl 0x7fe190c0
gomp_tls_data>)

This apparently has SYMBOL_REF_TLS_MODEL (rtl) == TLS_MODEL_NONE, so we never
bail out the escape hatch and end up calling add_AT_addr() to create the
DW_AT_const_value that needs relocating against the undefined symbol.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41357

Reply via email to