diff mbox

Fix unresolved symbol with -gsplit-dwarf

Message ID 20131004162754.5AF1316058E@ccoutant.mtv.corp.google.com
State New
Headers show

Commit Message

Cary Coutant Oct. 4, 2013, 4:27 p.m. UTC
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  <ccoutant@google.com>

gcc/
	* dwarf2out.c (dw_sra_loc_expr): Release addr_table entries when
        discarding a location list expression (or a piece of one).
diff mbox

Patch

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