This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Fix PR debug/45088


Hello,

In the first example of the patch below the DW_AT_pointer_type
DIE describing the type of the C::ai member lacks the DW_AT_type
attribute, making C::ai look like if it had void* type in a debugger.

This is because the type of C::ai is the self-reference type of
C. When gen_type_die_with_usage sees that self-reference it recognizes
it as a typedef, tries to emit a DIE for that typedef but it's
lieutenant gen_decl_die refuses to do so because the typedef is
artificial. So it looks like the dwarf emitter is sometimes faced with
artificial typedefs it must drop on the floor, and sometimes with
artificial typedefs for which it has to emit the underlying type.

One possible way to do resolve that dilemma is [at the FE level] to
fixup the type of *ai to make it be A instead of the self-reference
type of A. I figure the fact that the self-reference type is different
from A itself should be kept as an implementation detail of the FE
anyway.

The second hunk of the patch below hopefully does the fixup during the
parsing of the simple-type-specifier production for cases where the
type is neither a template nor a template instantiation. This is
because the self-reference information is useful for those template
related classes to resolve some ambiguities later e.g, with
maybe_get_template_decl_from_type_decl.

I noticed we were trying to do a similar fixup in
check_elaborated_type_specifier but were failing in doing so, maybe
because the representation of self-reference types has changed since
then. The first hunk addresses that.

Bootstrapped and tested on x86-64-unknown-linux-gnu against trunk.

-- 
	Dodji

>From e4e8f472bbabae7ed2a23906cc14b90fe5d699f8 Mon Sep 17 00:00:00 2001
From: Dodji Seketeli <dodji@redhat.com>
Date: Thu, 11 Nov 2010 23:42:51 +0100
Subject: [PATCH] Fix PR debug/45088

gcc/cp/
	* parser.c (cp_parser_simple_type_specifier): Ensure
	self-reference type doesn't get through all the way to the
	debug info emitter.
	* decl.c (check_elaborated_type_specifier): Likewise.

gcc/testsuite/
	* g++.dg/debug/dwarf2/self-ref-1.C: New test.
	* g++.dg/debug/dwarf2/self-ref-2.C: Likewise.
---
 gcc/cp/decl.c                                  |    2 +-
 gcc/cp/parser.c                                |   17 ++++++++++++++
 gcc/testsuite/g++.dg/debug/dwarf2/self-ref-1.C |   28 +++++++++++++++++++++++
 gcc/testsuite/g++.dg/debug/dwarf2/self-ref-2.C |   29 ++++++++++++++++++++++++
 4 files changed, 75 insertions(+), 1 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/debug/dwarf2/self-ref-1.C
 create mode 100644 gcc/testsuite/g++.dg/debug/dwarf2/self-ref-2.C

diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index fb5ca7f..feba130 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -10902,7 +10902,7 @@ check_elaborated_type_specifier (enum tag_types tag_code,
      name lookup will find the TYPE_DECL for the implicit "S::S"
      typedef.  Adjust for that here.  */
   if (DECL_SELF_REFERENCE_P (decl))
-    decl = TYPE_NAME (TREE_TYPE (decl));
+    decl = TYPE_NAME (DECL_ORIGINAL_TYPE (decl));
 
   type = TREE_TYPE (decl);
 
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 6a9e4d7..c3ed5b2 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -12791,6 +12791,23 @@ cp_parser_simple_type_specifier (cp_parser* parser,
       /* Otherwise, look for a type-name.  */
       else
 	type = cp_parser_type_name (parser);
+
+      /* Self reference typedefs should not be kept because it
+	 confuses the debug info emitter that wouldn't know how to
+	 tell the difference between an artificial typedef to drop
+	 and an artificial self reference typedef to keep.
+	 So let's replace the self reference by the type by its
+	 underlying type.  */
+      if (type && TREE_CODE (type) == TYPE_DECL
+	  && DECL_SELF_REFERENCE_P (type)
+	  /* If TYPE is a decl of a template or a template
+	     instantiation we need to keep it because the information
+	     is used later by e.g,
+	     maybe_get_template_decl_from_type_decl.  */
+	  && !CLASSTYPE_IS_TEMPLATE (TREE_TYPE (type))
+	  && !CLASSTYPE_TEMPLATE_INFO (TREE_TYPE (type)))
+	type = TYPE_NAME (DECL_ORIGINAL_TYPE (type));
+
       /* Keep track of all name-lookups performed in class scopes.  */
       if (type
 	  && !global_p
diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/self-ref-1.C b/gcc/testsuite/g++.dg/debug/dwarf2/self-ref-1.C
new file mode 100644
index 0000000..ee8342b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/debug/dwarf2/self-ref-1.C
@@ -0,0 +1,28 @@
+// Origin: PR debug/45088
+// { dg-do compile }
+// { dg-options "-g -dA" }
+// { dg-final { scan-assembler-times "\[^\n\r\]*\\(DIE\[^\n\r\]*DW_TAG_pointer_type\\)\[\n\r\]{1,2}\[^\n\r\]*DW_AT_byte_size\[\n\r\]{1,2}\[^\n\r\]*DW_AT_type" 3 } }
+
+struct A
+{
+    virtual ~A();
+};
+
+struct B : public A
+{
+    virtual ~B(){}
+};
+
+struct C : public B
+{
+    A* a1;
+};
+
+int
+main()
+{
+    C c;
+    c.a1 = 0;
+    return 0;
+}
+
diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/self-ref-2.C b/gcc/testsuite/g++.dg/debug/dwarf2/self-ref-2.C
new file mode 100644
index 0000000..b1c5401
--- /dev/null
+++ b/gcc/testsuite/g++.dg/debug/dwarf2/self-ref-2.C
@@ -0,0 +1,29 @@
+// Origin: PR debug/45088
+// { dg-do compile }
+// { dg-options "-g -dA" }
+// { dg-final { scan-assembler-times "\[^\n\r\]*\\(DIE\[^\n\r\]*DW_TAG_pointer_type\\)\[\n\r\]{1,2}\[^\n\r\]*DW_AT_byte_size\[\n\r\]{1,2}\[^\n\r\]*DW_AT_type" 4 } }
+
+template<class T>
+struct A
+{
+    virtual ~A();
+};
+
+struct B : public A<int>
+{
+    virtual ~B(){}
+};
+
+struct C : public B
+{
+    A<int>* a1;
+};
+
+int
+main()
+{
+    C c;
+    c.a1 = 0;
+    return 0;
+}
+
-- 
1.7.2.3


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]