aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDodji Seketeli <dodji@redhat.com>2008-11-12 21:57:44 +0000
committerDodji Seketeli <dodji@redhat.com>2008-11-12 21:57:44 +0000
commitd05c66d0fa99857c9f3833e2329a1756f59013eb (patch)
tree4bc0a17b6a59171e39ad721b6863cf81bef60b30
parent32cc0d4d21e187bf9da96fabeb0ab5e5c1ca5bd1 (diff)
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. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@141807 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/cgraph.c6
-rw-r--r--gcc/cgraph.h3
-rw-r--r--gcc/cgraphunit.c9
-rw-r--r--gcc/final.c4
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/debug/dwarf2/local-var-in-contructor.C30
7 files changed, 66 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index ac94fbc68e6..2cd719a87ae 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/cgraph.c b/gcc/cgraph.c
index 73dbfb3aa8b..43659cbdc6f 100644
--- a/gcc/cgraph.c
+++ b/gcc/cgraph.c
@@ -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. */
diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index a6018dc8910..782580466dd 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -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;
diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index 7c845733327..cd58c2aae0b 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -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,
diff --git a/gcc/final.c b/gcc/final.c
index e2d9e5a9766..d00790797dd 100644
--- a/gcc/final.c
+++ b/gcc/final.c
@@ -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),
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 783b08fbc51..7a07fbda344 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 00000000000..d61d27fe7e4
--- /dev/null
+++ b/gcc/testsuite/g++.dg/debug/dwarf2/local-var-in-contructor.C
@@ -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;
+}
+