OSDN Git Service

PR debug/41438
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 29 Sep 2009 17:33:58 +0000 (17:33 +0000)
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 29 Sep 2009 17:33:58 +0000 (17:33 +0000)
* dwarf2out.c (const_ok_for_output_1, const_ok_for_output): New
functions.
(mem_loc_descriptor, loc_descriptor, add_const_value_attribute): Bail
out if !const_ok_for_output.

PR debug/41474
* dwarf2out.c (mem_loc_descriptor) <case CONCAT, case CONCATN,
case VAR_LOCATION>: Remove gcc_unreachable ().

* gcc.dg/debug/dwarf2/const-1.c: Add dg-require-visibility, make x
hidden.
* g++.dg/debug/dwarf2/const-1.C: Likewise.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@152282 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/dwarf2out.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/debug/dwarf2/const1.C
gcc/testsuite/gcc.dg/debug/dwarf2/const-1.c

index e8696db..b0fdb7d 100644 (file)
@@ -1,3 +1,15 @@
+2009-09-29  Jakub Jelinek  <jakub@redhat.com>
+
+       PR debug/41438
+       * dwarf2out.c (const_ok_for_output_1, const_ok_for_output): New
+       functions.
+       (mem_loc_descriptor, loc_descriptor, add_const_value_attribute): Bail
+       out if !const_ok_for_output.
+
+       PR debug/41474
+       * dwarf2out.c (mem_loc_descriptor) <case CONCAT, case CONCATN,
+       case VAR_LOCATION>: Remove gcc_unreachable ().
+
 2009-09-29  Harsha Jagasia  <harsha.jagasia@amd.com>
 
        * config.gcc (i[34567]86-*-*): Remove mmintrin-common.h.
index 1c59d26..43e1a7b 100644 (file)
@@ -11104,6 +11104,70 @@ expansion_failed (tree expr, rtx rtl, char const *reason)
     }
 }
 
+/* Helper function for const_ok_for_output, called either directly
+   or via for_each_rtx.  */
+
+static int
+const_ok_for_output_1 (rtx *rtlp, void *data ATTRIBUTE_UNUSED)
+{
+  rtx rtl = *rtlp;
+
+  if (GET_CODE (rtl) != SYMBOL_REF)
+    return 0;
+
+  if (CONSTANT_POOL_ADDRESS_P (rtl))
+    {
+      bool marked;
+      get_pool_constant_mark (rtl, &marked);
+      /* If all references to this pool constant were optimized away,
+        it was not output and thus we can't represent it.  */
+      if (!marked)
+       {
+         expansion_failed (NULL_TREE, rtl,
+                           "Constant was removed from constant pool.\n");
+         return 1;
+       }
+    }
+
+  if (SYMBOL_REF_TLS_MODEL (rtl) != TLS_MODEL_NONE)
+    return 1;
+
+  /* Avoid references to external symbols in debug info, on several targets
+     the linker might even refuse to link when linking a shared library,
+     and in many other cases the relocations for .debug_info/.debug_loc are
+     dropped, so the address becomes zero anyway.  Hidden symbols, guaranteed
+     to be defined within the same shared library or executable are fine.  */
+  if (SYMBOL_REF_EXTERNAL_P (rtl))
+    {
+      tree decl = SYMBOL_REF_DECL (rtl);
+
+      if (decl == NULL || !targetm.binds_local_p (decl))
+       {
+         expansion_failed (NULL_TREE, rtl,
+                           "Symbol not defined in current TU.\n");
+         return 1;
+       }
+    }
+
+  return 0;
+}
+
+/* Return true if constant RTL can be emitted in DW_OP_addr or
+   DW_AT_const_value.  TLS SYMBOL_REFs, external SYMBOL_REFs or
+   non-marked constant pool SYMBOL_REFs can't be referenced in it.  */
+
+static bool
+const_ok_for_output (rtx rtl)
+{
+  if (GET_CODE (rtl) == SYMBOL_REF)
+    return const_ok_for_output_1 (&rtl, NULL) == 0;
+
+  if (GET_CODE (rtl) == CONST)
+    return for_each_rtx (&XEXP (rtl, 0), const_ok_for_output_1, NULL) == 0;
+
+  return true;
+}
+
 /* The following routine converts the RTL for a variable or parameter
    (resident in memory) into an equivalent Dwarf representation of a
    mechanism for getting the address of that same variable onto the top of a
@@ -11278,6 +11342,9 @@ mem_loc_descriptor (rtx rtl, enum machine_mode mode,
          break;
        }
 
+      if (!const_ok_for_output (rtl))
+       break;
+
       mem_loc_result = new_loc_descr (DW_OP_addr, 0, 0);
       mem_loc_result->dw_loc_oprnd1.val_class = dw_val_class_addr;
       mem_loc_result->dw_loc_oprnd1.v.val_addr = rtl;
@@ -11289,7 +11356,6 @@ mem_loc_descriptor (rtx rtl, enum machine_mode mode,
     case VAR_LOCATION:
       expansion_failed (NULL_TREE, rtl,
                        "CONCAT/CONCATN/VAR_LOCATION is handled only by loc_descriptor");
-      gcc_unreachable ();
       return 0;
 
     case PRE_MODIFY:
@@ -11987,8 +12053,7 @@ loc_descriptor (rtx rtl, enum machine_mode mode,
        }
       /* FALLTHROUGH */
     case SYMBOL_REF:
-      if (GET_CODE (rtl) == SYMBOL_REF
-         && SYMBOL_REF_TLS_MODEL (rtl) != TLS_MODEL_NONE)
+      if (!const_ok_for_output (rtl))
        break;
     case LABEL_REF:
       if (mode != VOIDmode && GET_MODE_SIZE (mode) == DWARF2_ADDR_SIZE
@@ -12569,7 +12634,7 @@ loc_list_from_tree (tree loc, int want_address)
            expansion_failed (loc, NULL_RTX, "CONST_STRING");
            return 0;
          }
-       else if (CONSTANT_P (rtl))
+       else if (CONSTANT_P (rtl) && const_ok_for_output (rtl))
          {
            ret = new_loc_descr (DW_OP_addr, 0, 0);
            ret->dw_loc_oprnd1.val_class = dw_val_class_addr;
@@ -12919,8 +12984,11 @@ loc_list_from_tree (tree loc, int want_address)
                            "DWARF address size mismatch");
          return 0;
        }
-      add_loc_descr_to_each (list_ret,
-                            new_loc_descr (DW_OP_stack_value, 0, 0));
+      if (ret)
+       add_loc_descr (&ret, new_loc_descr (DW_OP_stack_value, 0, 0));
+      else
+       add_loc_descr_to_each (list_ret,
+                              new_loc_descr (DW_OP_stack_value, 0, 0));
       have_address = 1;
     }
   /* Show if we can't fill the request for an address.  */
@@ -13465,8 +13533,7 @@ add_const_value_attribute (dw_die_ref die, rtx rtl)
        return add_const_value_attribute (die, XEXP (rtl, 0));
       /* FALLTHROUGH */
     case SYMBOL_REF:
-      if (GET_CODE (rtl) == SYMBOL_REF
-         && SYMBOL_REF_TLS_MODEL (rtl) != TLS_MODEL_NONE)
+      if (!const_ok_for_output (rtl))
        return false;
     case LABEL_REF:
       add_AT_addr (die, DW_AT_const_value, rtl);
index c9a0244..fd019e2 100644 (file)
@@ -1,3 +1,10 @@
+2009-09-29  Jakub Jelinek  <jakub@redhat.com>
+
+       PR debug/41438
+       * gcc.dg/debug/dwarf2/const-1.c: Add dg-require-visibility, make x
+       hidden.
+       * g++.dg/debug/dwarf2/const-1.C: Likewise.
+
 2009-09-29  Harsha Jagasia  <harsha.jagasia@amd.com>
 
        * gcc.target/i386/i386.exp: Remove check_effective_target_sse5.
index be23c10..eaed5bd 100644 (file)
@@ -1,6 +1,7 @@
 /* { dg-do compile } */
 /* { dg-options "-O -gdwarf-2 -dA" } */
+/* { dg-require-visibility "" } */
 /* { dg-final { scan-assembler "DW_AT_const_value" } } */
 
-extern void x ();
+extern void x () __attribute__((visibility ("hidden")));
 void (* const f) () = x;
index aa20e6d..26aa9bd 100644 (file)
@@ -1,6 +1,7 @@
 /* { dg-do compile } */
 /* { dg-options "-O -gdwarf-2 -dA" } */
+/* { dg-require-visibility "" } */
 /* { dg-final { scan-assembler "DW_AT_const_value" } } */
 
-extern void x();
+extern void x() __attribute__((visibility("hidden")));
 static void (*f)() = x;