2008-11-17 Dodji Seketeli <dodji@redhat.com> PR c++/27574 * cgraph.c (cgraph_remove_node): Do not remove the body of abstract functions. It might be useful to emit debugging information. This is a patch from Ian Lance Taylor. * cgraphunit.c (cgraph_optimize): Do not cry when bodies of abstract functions are still around. They are useful to output debug info. PR c++/27574 * g++.dg/debug/dwarf2/dwarf2.exp: Backport this here from gcc-4_3-branch. * g++.dg/debug/dwarf2/local-var-in-contructor.C: New testcase. --- gcc/cgraph.c.jj 2007-02-05 11:53:00.000000000 +0100 +++ gcc/cgraph.c 2009-10-09 11:21:27.000000000 +0200 @@ -479,6 +479,14 @@ cgraph_remove_node (struct cgraph_node * kill_body = true; } + /* We don't release the body of abstract functions, because they may + be needed when emitting debugging information. In particular + this will happen for C++ constructors/destructors. FIXME: + Ideally we would check to see whether there are any reachable + functions whose DECL_ABSTRACT_ORIGIN points to this decl. */ + if (DECL_ABSTRACT (node->decl)) + kill_body = false; + if (kill_body && !dump_enabled_p (TDI_tree_all) && flag_unit_at_a_time) { DECL_SAVED_TREE (node->decl) = NULL; --- gcc/cgraphunit.c.jj 2007-02-05 11:53:00.000000000 +0100 +++ gcc/cgraphunit.c 2009-10-09 11:24:35.000000000 +0200 @@ -1391,7 +1391,10 @@ cgraph_optimize (void) for (node = cgraph_nodes; node; node = node->next) if (node->analyzed && (node->global.inlined_to - || DECL_SAVED_TREE (node->decl))) + || DECL_SAVED_TREE (node->decl)) + /* Abstract functions are needed to output debug info, + so don't complain about them if they are still around. */ + && !DECL_ABSTRACT (node->decl)) { error_found = true; dump_cgraph_node (stderr, node); --- gcc/testsuite/g++.dg/debug/dwarf2/dwarf2.exp.jj 2009-10-09 11:20:19.000000000 +0200 +++ gcc/testsuite/g++.dg/debug/dwarf2/dwarf2.exp 2009-10-09 11:20:19.000000000 +0200 @@ -0,0 +1,43 @@ +# Copyright (C) 2007, 2007 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GCC; see the file COPYING3. If not see +# <http://www.gnu.org/licenses/>. + +# G++ testsuite that uses the `dg.exp' driver. + +# Load support procs. +load_lib g++-dg.exp + +# If a testcase doesn't have special options, use these. +global DEFAULT_CFLAGS +if ![info exists DEFAULT_CFLAGS] then { + set DEFAULT_CFLAGS " -gdwarf-2" +} + +# Initialize `dg'. +dg-init + +# Main loop. +set comp_output [g++_target_compile \ + "$srcdir/$subdir/../trivial.C" "trivial.S" assembly \ + "additional_flags=-gdwarf-2"] +if { ! [string match "*: target system does not support the * debug format*" \ + $comp_output] } { + remove-build-file "trivial.S" + dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[C\]]] \ + "" $DEFAULT_CFLAGS +} + +# All done. +dg-finish --- gcc/testsuite/g++.dg/debug/dwarf2/local-var-in-contructor.C.jj 2009-10-09 11:20:19.000000000 +0200 +++ gcc/testsuite/g++.dg/debug/dwarf2/local-var-in-contructor.C 2009-10-09 11:20:19.000000000 +0200 @@ -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; +} +