OSDN Git Service

PR debug/5770
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 26 Feb 2002 21:08:57 +0000 (21:08 +0000)
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 26 Feb 2002 21:08:57 +0000 (21:08 +0000)
* dwarf2out.c (rtl_for_decl_location): Return CONST_STRING for
STRING_CST initializer spanning the whole variable without
embedded zeros.
If expand_expr returned MEM, don't use it.

* g++.dg/debug/debug4.C: New test.

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

gcc/ChangeLog
gcc/dwarf2out.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/debug/debug4.C [new file with mode: 0644]

index 2918066..b4da9bf 100644 (file)
@@ -1,3 +1,11 @@
+2002-02-26  Jakub Jelinek  <jakub@redhat.com>
+
+       PR debug/5770
+       * dwarf2out.c (rtl_for_decl_location): Return CONST_STRING for
+       STRING_CST initializer spanning the whole variable without
+       embedded zeros.
+       If expand_expr returned MEM, don't use it.
+
 2002-02-26  Alexandre Oliva  <aoliva@redhat.com>
 
        * dwarf2out.c (gen_inlined_subroutine_die): If block is abstract,
index f4c298a..6c08939 100644 (file)
@@ -8902,8 +8902,38 @@ rtl_for_decl_location (decl)
      and will have been substituted directly into all expressions that use it.
      C does not have such a concept, but C++ and other languages do.  */
   else if (TREE_CODE (decl) == VAR_DECL && DECL_INITIAL (decl))
-    rtl = expand_expr (DECL_INITIAL (decl), NULL_RTX, VOIDmode,
-                      EXPAND_INITIALIZER);
+    {
+      /* If a variable is initialized with a string constant without embedded
+        zeros, build CONST_STRING.  */
+      if (TREE_CODE (DECL_INITIAL (decl)) == STRING_CST
+         && TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
+       {
+         tree arrtype = TREE_TYPE (decl);
+         tree enttype = TREE_TYPE (arrtype);
+         tree domain = TYPE_DOMAIN (arrtype);
+         tree init = DECL_INITIAL (decl);
+         enum machine_mode mode = TYPE_MODE (enttype);
+
+         if (GET_MODE_CLASS (mode) == MODE_INT && GET_MODE_SIZE (mode) == 1
+             && domain
+             && integer_zerop (TYPE_MIN_VALUE (domain))
+             && compare_tree_int (TYPE_MAX_VALUE (domain),
+                                  TREE_STRING_LENGTH (init) - 1) == 0
+             && ((size_t) TREE_STRING_LENGTH (init)
+                 == strlen (TREE_STRING_POINTER (init)) + 1))
+           rtl = gen_rtx_CONST_STRING (VOIDmode, TREE_STRING_POINTER (init));
+       }
+
+      if (rtl == NULL)
+       {
+         rtl = expand_expr (DECL_INITIAL (decl), NULL_RTX, VOIDmode,
+                            EXPAND_INITIALIZER);
+         /* If expand_expr returned a MEM, we cannot use it, since
+            it won't be output, leading to unresolved symbol.  */
+         if (rtl && GET_CODE (rtl) == MEM)
+           rtl = NULL;
+       }
+    }
 
   return rtl;
 }
index 8505241..e45f949 100644 (file)
@@ -1,3 +1,7 @@
+2002-02-26  Jakub Jelinek  <jakub@redhat.com>
+
+       * g++.dg/debug/debug4.C: New test.
+
 2002-02-26  Alexandre Oliva  <aoliva@redhat.com>
 
        * gcc.dg/debug/20020224-1.c: New.
diff --git a/gcc/testsuite/g++.dg/debug/debug4.C b/gcc/testsuite/g++.dg/debug/debug4.C
new file mode 100644 (file)
index 0000000..8dceb08
--- /dev/null
@@ -0,0 +1,17 @@
+/* PR debug/5770
+   This testcase failed at -O -g because the following constants
+   were optimized away since they were never referenced, but
+   since they are variables with initializers, rtl_for_decl_location
+   run expand_expr on their initializers and returned it.
+   This lead to references to constants which were deferred and thus
+   never emitted.  */
+/* { dg-do link } */
+
+static const char foo[] = "foo string";
+static const char bar[30] = "bar string";
+static const wchar_t baz[] = L"baz string";
+
+int
+main ()
+{
+}