]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR debug/27574 (MIssing debug info at -O0 for a local variable in a C++ constructor)
authorDodji Seketeli <dodji@redhat.com>
Wed, 12 Nov 2008 21:57:44 +0000 (21:57 +0000)
committerDodji Seketeli <dodji@gcc.gnu.org>
Wed, 12 Nov 2008 21:57:44 +0000 (22:57 +0100)
gcc/ChangeLog:
2008-11-12  Dodji Seketeli  <dodji@redhat.com>

PR debug/27574
* cgraph.h: New abstract_and_needed member to struct cgraph_node.
* cgraphunit.c (cgraph_analyze_functions): Flag abstract functions
- which clones are reachable - as "abstract and needed".
* cgraph.c (cgraph_release_function_body):  If a node is "abstract and needed",
do not release its DECL_INITIAL() content because that will be needed to emit
debug info.

gcc/testsuite/ChangeLog:
2008-11-12  Dodji Seketeli  <dodji@redhat.com>

PR debug/27574
* g++.dg/debug/dwarf2/local-var-in-contructor.C: New test.

From-SVN: r141807

gcc/ChangeLog
gcc/cgraph.c
gcc/cgraph.h
gcc/cgraphunit.c
gcc/final.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/debug/dwarf2/local-var-in-contructor.C [new file with mode: 0644]

index ac94fbc68e641054d649b12cacc4afd6fda6aabc..2cd719a87ae5ecb3a4c91fb08b108a0333f4b5ac 100644 (file)
@@ -1,3 +1,13 @@
+2008-11-12  Dodji Seketeli  <dodji@redhat.com>
+
+       PR debug/27574
+       * cgraph.h: New abstract_and_needed member to struct cgraph_node.
+       * cgraphunit.c (cgraph_analyze_functions): Flag abstract functions
+       - which clones are reachable - as "abstract and needed".
+       * cgraph.c (cgraph_release_function_body):  If a node is "abstract and needed",
+       do not release its DECL_INITIAL() content because that will be needed to emit
+       debug info.
+
 2008-11-12  Steve Ellcey  <sje@cup.hp.com>
 
        PR target/27880
index 73dbfb3aa8b44ef6e16f2ba0608debf8ce034deb..43659cbdc6f1c1ec6b418bc9481dd7f899025beb 100644 (file)
@@ -936,7 +936,11 @@ cgraph_release_function_body (struct cgraph_node *node)
       DECL_STRUCT_FUNCTION (node->decl) = NULL;
     }
   DECL_SAVED_TREE (node->decl) = NULL;
-  DECL_INITIAL (node->decl) = error_mark_node;
+  /* If the node is abstract and needed, then do not clear DECL_INITIAL
+     of its associated function function declaration because it's
+     needed to emit debug info later.  */
+  if (!node->abstract_and_needed)
+    DECL_INITIAL (node->decl) = error_mark_node;
 }
 
 /* Remove the node from cgraph.  */
index a6018dc89101ecfc3d5a70aaf8121e2cdff680e4..782580466dd5e2851a3f96b9a9cef30e5d4e1172 100644 (file)
@@ -166,6 +166,9 @@ struct cgraph_node GTY((chain_next ("%h.next"), chain_prev ("%h.previous")))
   /* Set when function must be output - it is externally visible
      or its address is taken.  */
   unsigned needed : 1;
+  /* Set when decl is an abstract function pointed to by the
+     ABSTRACT_DECL_ORIGIN of a reachable function.  */
+  unsigned abstract_and_needed : 1;
   /* Set when function is reachable by call from other function
      that is either reachable or needed.  */
   unsigned reachable : 1;
index 7c845733327e718aa021937c855d90f17e627f8a..cd58c2aae0b3d1e071e8be48dcaf291b951ddc18 100644 (file)
@@ -896,6 +896,15 @@ cgraph_analyze_functions (void)
        if (!edge->callee->reachable)
          cgraph_mark_reachable_node (edge->callee);
 
+      /* If decl is a clone of an abstract function, mark that abstract
+        function so that we don't release its body. The DECL_INITIAL() of that
+         abstract function declaration will be later needed to output debug info.  */
+      if (DECL_ABSTRACT_ORIGIN (decl))
+       {
+         struct cgraph_node *origin_node = cgraph_node (DECL_ABSTRACT_ORIGIN (decl));
+         origin_node->abstract_and_needed = true;
+       }
+
       /* We finalize local static variables during constructing callgraph
          edges.  Process their attributes too.  */
       process_function_and_variable_attributes (first_processed,
index e2d9e5a9766361c6980d781aac752f0f366bd155..d00790797dd34405db94020bbd36597b75a9c454 100644 (file)
@@ -4187,6 +4187,10 @@ rest_of_handle_final (void)
   timevar_push (TV_SYMOUT);
   (*debug_hooks->function_decl) (current_function_decl);
   timevar_pop (TV_SYMOUT);
+
+  /* Release the blocks that are linked to DECL_INITIAL() to free the memory.  */
+  DECL_INITIAL (current_function_decl) = error_mark_node;
+
   if (DECL_STATIC_CONSTRUCTOR (current_function_decl)
       && targetm.have_ctors_dtors)
     targetm.asm_out.constructor (XEXP (DECL_RTL (current_function_decl), 0),
index 783b08fbc5183bfee5c35282bf859172d104df4b..7a07fbda3442848c1e6842e293ba02852a65b235 100644 (file)
@@ -1,3 +1,8 @@
+2008-11-12  Dodji Seketeli  <dodji@redhat.com>
+
+       PR debug/27574
+       * g++.dg/debug/dwarf2/local-var-in-contructor.C: New test.
+
 2008-11-12  Eric Botcazou  <ebotcazou@adacore.com>
 
        * gcc.c-torture/execute/20081112-1.c: New test.
diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/local-var-in-contructor.C b/gcc/testsuite/g++.dg/debug/dwarf2/local-var-in-contructor.C
new file mode 100644 (file)
index 0000000..d61d27f
--- /dev/null
@@ -0,0 +1,30 @@
+// Contributed by Dodji Seketeli <dodji@redhat.com>
+// Origin PR27574
+// { dg-do compile }
+// { dg-options "-O0 -g" }
+// { dg-final { scan-assembler "problem" } }
+
+void f (int *)
+{
+}
+
+class A
+{
+public:
+ A(int i);
+};
+
+A::A(int i)
+{
+ int *problem = new int(i);
+ f (problem);
+}
+
+int
+main (void)
+{
+  A a (0);
+
+  return 0;
+}
+