diff mbox

pr/54508: fix incomplete debug information for class

Message ID C75A84166056C94F84D238A44AF9F6AD216630@AUSX10MPC103.AMER.DELL.COM
State New
Headers show

Commit Message

Paul Koning Sept. 17, 2012, 9:24 p.m. UTC
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.

Comments

Paul Koning Sept. 20, 2012, 8:55 p.m. UTC | #1
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);
}
Paul Koning Sept. 24, 2012, 6:41 p.m. UTC | #2
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);
> }
>
diff mbox

Patch

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);
+}