Message ID | C75A84166056C94F84D238A44AF9F6AD216630@AUSX10MPC103.AMER.DELL.COM |
---|---|
State | New |
Headers | show |
Attached below is an update to the testcase file, to fix the scan-assembler regexp comment character matching. This uses the same regexp element that H-P Nilsson used in the fix to nested-3.C two days ago. By the way, I ran check-g++ for dwarf2.exp on this change, no regressions. Ok to commit? paul On Sep 17, 2012, at 5:24 PM, <Paul_Koning@Dell.com> <Paul_Koning@Dell.com> wrote: > If the only reference in a source file is to a static method of a class, then GCC would output debug information for the class name but not any of its members or base classes. The attached patch fixes this by having "prune_unused_types_mark" mark all of the parent's children if the parent DIE type is for a class. > > The associated new testcase verifies this, and also verifies this that references to a function in a namespace do *not* cause other parts of that namespace to be emitted as debug information, but that references to a method in a class (or struct or union) do emit the other information for that class. > > Ok to commit? This would close PR/54508. > > paul > > ChangeLog: > > 2012-09-17 Paul Koning <ni1d@arrl.net> > > * dwarf2out.c (prune_unused_types_mark): Mark all of parent's > children if parent is a class. > > testsuite/ChangeLog: > > 2012-09-17 Paul Koning <ni1d@arrl.net> > > * g++.dg/debug/dwarf2/pr54508.C: New. > > Index: gcc/dwarf2out.c > =================================================================== > --- gcc/dwarf2out.c (revision 191408) > +++ gcc/dwarf2out.c (working copy) > @@ -21033,9 +21033,13 @@ > prune_unused_types_mark_generic_parms_dies (die); > > /* We also have to mark its parents as used. > - (But we don't want to mark our parents' kids due to this.) */ > + (But we don't want to mark our parent's kids due to this, > + unless it is a class.) */ > if (die->die_parent) > - prune_unused_types_mark (die->die_parent, 0); > + prune_unused_types_mark (die->die_parent, > + (die->die_parent->die_tag == DW_TAG_class_type || > + die->die_parent->die_tag == DW_TAG_structure_type || > + die->die_parent->die_tag == DW_TAG_union_type)); > > /* Mark any referenced nodes. */ > prune_unused_types_walk_attribs (die); > Index: gcc/testsuite/g++.dg/debug/dwarf2/pr54508.C > =================================================================== > --- gcc/testsuite/g++.dg/debug/dwarf2/pr54508.C (revision 0) > +++ gcc/testsuite/g++.dg/debug/dwarf2/pr54508.C (revision 0) > @@ -0,0 +1,67 @@ > +// PR debug/54508 > +// { dg-do compile } > +// { dg-options "-g2 -dA" } > + > +// { dg-final { scan-assembler "\"cbase\\\\0\"\[ \t\]+\# DW_AT_name\|DW_AT_name: \"cbase\"" } } > +// { dg-final { scan-assembler "\"OPCODE\\\\0\"\[ \t\]+\# DW_AT_name\|DW_AT_name: \"OPCODE\"" } } > +// { dg-final { scan-assembler "\"bi\\\\0\"\[ \t\]+\# DW_AT_name" } } > +// { dg-final { scan-assembler "\"si\\\\0\"\[ \t\]+\# DW_AT_name" } } > +// { dg-final { scan-assembler "\"f1\\\\0\"\[ \t\]+\# DW_AT_name" } } > +// { dg-final { scan-assembler "\"f2\\\\0\"\[ \t\]+\# DW_AT_name" } } > +// { dg-final { scan-assembler-not "\"nc\\\\0\"\[ \t\]+\# DW_AT_name\|DW_AT_name: \"nc\"" } } > +... // PR debug/54508 // { dg-do compile } // { dg-options "-g2 -dA" } // { dg-final { scan-assembler "\"cbase\\\\0\"\[ \t\]+\[#;/!|@\]+ DW_AT_name\|DW_AT_name: \"cbase\"" } } // { dg-final { scan-assembler "\"OPCODE\\\\0\"\[ \t\]+\[#;/!|@\]+ DW_AT_name\|DW_AT_name: \"OPCODE\"" } } // { dg-final { scan-assembler "\"bi\\\\0\"\[ \t\]+\[#;/!|@\]+ DW_AT_name" } } // { dg-final { scan-assembler "\"si\\\\0\"\[ \t\]+\[#;/!|@\]+ DW_AT_name" } } // { dg-final { scan-assembler "\"f1\\\\0\"\[ \t\]+\[#;/!|@\]+ DW_AT_name" } } // { dg-final { scan-assembler "\"f2\\\\0\"\[ \t\]+\[#;/!|@\]+ DW_AT_name" } } // { dg-final { scan-assembler-not "\"nc\\\\0\"\[ \t\]+\# DW_AT_name\|DW_AT_name: \"nc\"" } } class cbase { public: static int si; int bi; }; class c : public cbase { public: enum { OPCODE = 251 }; int i ; static const char *testc (void) { return "foo"; } }; struct s { int f1; static const char *tests (void) { return "test"; } }; union u { int f2; double d; static const char *testu (void) { return "test union"; } }; namespace n { const char *ntest (void) { return "test n"; } class nc { public: int i; static int sj; }; } extern void send (int, int, const void *, int); void test (int src) { int cookie = 1; send(src, c::OPCODE, c::testc (), cookie); send(src, c::OPCODE, s::tests (), cookie); send(src, c::OPCODE, u::testu (), cookie); send(src, c::OPCODE, n::ntest (), cookie); }
Ping... paul Begin forwarded message: > From: <Paul_Koning@Dell.com> > Date: September 20, 2012 4:55:05 PM EDT > To: <gcc-patches@gcc.gnu.org> > Subject: Re: [patch] pr/54508: fix incomplete debug information for class > > Attached below is an update to the testcase file, to fix the scan-assembler regexp comment character matching. This uses the same regexp element that H-P Nilsson used in the fix to nested-3.C two days ago. > > By the way, I ran check-g++ for dwarf2.exp on this change, no regressions. > > Ok to commit? > > paul > > On Sep 17, 2012, at 5:24 PM, <Paul_Koning@Dell.com> > <Paul_Koning@Dell.com> wrote: > >> If the only reference in a source file is to a static method of a class, then GCC would output debug information for the class name but not any of its members or base classes. The attached patch fixes this by having "prune_unused_types_mark" mark all of the parent's children if the parent DIE type is for a class. >> >> The associated new testcase verifies this, and also verifies this that references to a function in a namespace do *not* cause other parts of that namespace to be emitted as debug information, but that references to a method in a class (or struct or union) do emit the other information for that class. >> >> Ok to commit? This would close PR/54508. >> >> paul >> >> ChangeLog: >> >> 2012-09-17 Paul Koning <ni1d@arrl.net> >> >> * dwarf2out.c (prune_unused_types_mark): Mark all of parent's >> children if parent is a class. >> >> testsuite/ChangeLog: >> >> 2012-09-17 Paul Koning <ni1d@arrl.net> >> >> * g++.dg/debug/dwarf2/pr54508.C: New. >> >> Index: gcc/dwarf2out.c >> =================================================================== >> --- gcc/dwarf2out.c (revision 191408) >> +++ gcc/dwarf2out.c (working copy) >> @@ -21033,9 +21033,13 @@ >> prune_unused_types_mark_generic_parms_dies (die); >> >> /* We also have to mark its parents as used. >> - (But we don't want to mark our parents' kids due to this.) */ >> + (But we don't want to mark our parent's kids due to this, >> + unless it is a class.) */ >> if (die->die_parent) >> - prune_unused_types_mark (die->die_parent, 0); >> + prune_unused_types_mark (die->die_parent, >> + (die->die_parent->die_tag == DW_TAG_class_type || >> + die->die_parent->die_tag == DW_TAG_structure_type || >> + die->die_parent->die_tag == DW_TAG_union_type)); >> >> /* Mark any referenced nodes. */ >> prune_unused_types_walk_attribs (die); >> Index: gcc/testsuite/g++.dg/debug/dwarf2/pr54508.C >> =================================================================== >> --- gcc/testsuite/g++.dg/debug/dwarf2/pr54508.C (revision 0) >> +++ gcc/testsuite/g++.dg/debug/dwarf2/pr54508.C (revision 0) >> @@ -0,0 +1,67 @@ >> +// PR debug/54508 >> +// { dg-do compile } >> +// { dg-options "-g2 -dA" } >> + >> +// { dg-final { scan-assembler "\"cbase\\\\0\"\[ \t\]+\# DW_AT_name\|DW_AT_name: \"cbase\"" } } >> +// { dg-final { scan-assembler "\"OPCODE\\\\0\"\[ \t\]+\# DW_AT_name\|DW_AT_name: \"OPCODE\"" } } >> +// { dg-final { scan-assembler "\"bi\\\\0\"\[ \t\]+\# DW_AT_name" } } >> +// { dg-final { scan-assembler "\"si\\\\0\"\[ \t\]+\# DW_AT_name" } } >> +// { dg-final { scan-assembler "\"f1\\\\0\"\[ \t\]+\# DW_AT_name" } } >> +// { dg-final { scan-assembler "\"f2\\\\0\"\[ \t\]+\# DW_AT_name" } } >> +// { dg-final { scan-assembler-not "\"nc\\\\0\"\[ \t\]+\# DW_AT_name\|DW_AT_name: \"nc\"" } } >> +... > > // PR debug/54508 > // { dg-do compile } > // { dg-options "-g2 -dA" } > > // { dg-final { scan-assembler "\"cbase\\\\0\"\[ \t\]+\[#;/!|@\]+ DW_AT_name\|DW_AT_name: \"cbase\"" } } > // { dg-final { scan-assembler "\"OPCODE\\\\0\"\[ \t\]+\[#;/!|@\]+ DW_AT_name\|DW_AT_name: \"OPCODE\"" } } > // { dg-final { scan-assembler "\"bi\\\\0\"\[ \t\]+\[#;/!|@\]+ DW_AT_name" } } > // { dg-final { scan-assembler "\"si\\\\0\"\[ \t\]+\[#;/!|@\]+ DW_AT_name" } } > // { dg-final { scan-assembler "\"f1\\\\0\"\[ \t\]+\[#;/!|@\]+ DW_AT_name" } } > // { dg-final { scan-assembler "\"f2\\\\0\"\[ \t\]+\[#;/!|@\]+ DW_AT_name" } } > // { dg-final { scan-assembler-not "\"nc\\\\0\"\[ \t\]+\# DW_AT_name\|DW_AT_name: \"nc\"" } } > > class cbase > > { > public: > static int si; > int bi; > }; > > class c : public cbase > > { > public: > enum > { > OPCODE = 251 > }; > int i ; > static const char *testc (void) { return "foo"; } > }; > > struct s > { > int f1; > static const char *tests (void) { return "test"; } > }; > > union u > { > int f2; > double d; > static const char *testu (void) { return "test union"; } > }; > > namespace n > { > const char *ntest (void) { return "test n"; } > > class nc > { > public: > int i; > static int sj; > }; > } > > extern void send (int, int, const void *, int); > > void test (int src) > { > int cookie = 1; > send(src, c::OPCODE, c::testc (), cookie); > send(src, c::OPCODE, s::tests (), cookie); > send(src, c::OPCODE, u::testu (), cookie); > send(src, c::OPCODE, n::ntest (), cookie); > } >
Index: gcc/dwarf2out.c =================================================================== --- gcc/dwarf2out.c (revision 191408) +++ gcc/dwarf2out.c (working copy) @@ -21033,9 +21033,13 @@ prune_unused_types_mark_generic_parms_dies (die); /* We also have to mark its parents as used. - (But we don't want to mark our parents' kids due to this.) */ + (But we don't want to mark our parent's kids due to this, + unless it is a class.) */ if (die->die_parent) - prune_unused_types_mark (die->die_parent, 0); + prune_unused_types_mark (die->die_parent, + (die->die_parent->die_tag == DW_TAG_class_type || + die->die_parent->die_tag == DW_TAG_structure_type || + die->die_parent->die_tag == DW_TAG_union_type)); /* Mark any referenced nodes. */ prune_unused_types_walk_attribs (die); Index: gcc/testsuite/g++.dg/debug/dwarf2/pr54508.C =================================================================== --- gcc/testsuite/g++.dg/debug/dwarf2/pr54508.C (revision 0) +++ gcc/testsuite/g++.dg/debug/dwarf2/pr54508.C (revision 0) @@ -0,0 +1,67 @@ +// PR debug/54508 +// { dg-do compile } +// { dg-options "-g2 -dA" } + +// { dg-final { scan-assembler "\"cbase\\\\0\"\[ \t\]+\# DW_AT_name\|DW_AT_name: \"cbase\"" } } +// { dg-final { scan-assembler "\"OPCODE\\\\0\"\[ \t\]+\# DW_AT_name\|DW_AT_name: \"OPCODE\"" } } +// { dg-final { scan-assembler "\"bi\\\\0\"\[ \t\]+\# DW_AT_name" } } +// { dg-final { scan-assembler "\"si\\\\0\"\[ \t\]+\# DW_AT_name" } } +// { dg-final { scan-assembler "\"f1\\\\0\"\[ \t\]+\# DW_AT_name" } } +// { dg-final { scan-assembler "\"f2\\\\0\"\[ \t\]+\# DW_AT_name" } } +// { dg-final { scan-assembler-not "\"nc\\\\0\"\[ \t\]+\# DW_AT_name\|DW_AT_name: \"nc\"" } } + +class cbase + +{ +public: + static int si; + int bi; +}; + +class c : public cbase + +{ +public: + enum + { + OPCODE = 251 + }; + int i ; + static const char *testc (void) { return "foo"; } +}; + +struct s +{ + int f1; + static const char *tests (void) { return "test"; } +}; + +union u +{ + int f2; + double d; + static const char *testu (void) { return "test union"; } +}; + +namespace n +{ + const char *ntest (void) { return "test n"; } + + class nc + { + public: + int i; + static int sj; + }; +} + +extern void send (int, int, const void *, int); + +void test (int src) +{ + int cookie = 1; + send(src, c::OPCODE, c::testc (), cookie); + send(src, c::OPCODE, s::tests (), cookie); + send(src, c::OPCODE, u::testu (), cookie); + send(src, c::OPCODE, n::ntest (), cookie); +}