When building the location list for a variable that has been optimized by SRA, dw_sra_loc_expr sometimes creates a DWARF expression or a piece of an expression, but then abandons it for some reason. When abandoning it, we neglected to release any addr_table entries created for DW_OP_addr_index opcodes, occasionally resulting in a link-time unresolved symbol. This patch releases the addr_table entries before abandoning a location expression.
Bootstrapped and regression tested on x86-64. Committed to trunk at r203206. -cary 2013-10-03 Cary Coutant <ccout...@google.com> gcc/ * dwarf2out.c (dw_sra_loc_expr): Release addr_table entries when discarding a location list expression (or a piece of one). Index: dwarf2out.c =================================================================== --- dwarf2out.c (revision 203183) +++ dwarf2out.c (working copy) @@ -13492,6 +13492,9 @@ dw_sra_loc_expr (tree decl, rtx loc) if (last != NULL && opsize != bitsize) { padsize += bitsize; + /* Discard the current piece of the descriptor and release any + addr_table entries it uses. */ + remove_loc_list_addr_table_entries (cur_descr); continue; } @@ -13500,18 +13503,24 @@ dw_sra_loc_expr (tree decl, rtx loc) if (padsize) { if (padsize > decl_size) - return NULL; + { + remove_loc_list_addr_table_entries (cur_descr); + goto discard_descr; + } decl_size -= padsize; *descr_tail = new_loc_descr_op_bit_piece (padsize, 0); if (*descr_tail == NULL) - return NULL; + { + remove_loc_list_addr_table_entries (cur_descr); + goto discard_descr; + } descr_tail = &(*descr_tail)->dw_loc_next; padsize = 0; } *descr_tail = cur_descr; descr_tail = tail; if (bitsize > decl_size) - return NULL; + goto discard_descr; decl_size -= bitsize; if (last == NULL) { @@ -13547,9 +13556,9 @@ dw_sra_loc_expr (tree decl, rtx loc) { if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN && (memsize > BITS_PER_WORD || bitsize > BITS_PER_WORD)) - return NULL; + goto discard_descr; if (memsize < bitsize) - return NULL; + goto discard_descr; if (BITS_BIG_ENDIAN) offset = memsize - bitsize; } @@ -13557,7 +13566,7 @@ dw_sra_loc_expr (tree decl, rtx loc) *descr_tail = new_loc_descr_op_bit_piece (bitsize, offset); if (*descr_tail == NULL) - return NULL; + goto discard_descr; descr_tail = &(*descr_tail)->dw_loc_next; } } @@ -13568,9 +13577,14 @@ dw_sra_loc_expr (tree decl, rtx loc) { *descr_tail = new_loc_descr_op_bit_piece (decl_size, 0); if (*descr_tail == NULL) - return NULL; + goto discard_descr; } return descr; + +discard_descr: + /* Discard the descriptor and release any addr_table entries it uses. */ + remove_loc_list_addr_table_entries (descr); + return NULL; } /* Return the dwarf representation of the location list LOC_LIST of