Patchwork Improve handling of is_const_type && is_volatile_type in modified_type_die (PR debug/45997)

login
register
mail settings
Submitter Dodji Seketeli
Date Nov. 9, 2010, 9:28 p.m.
Message ID <m3hbfqqj95.fsf@seketeli.org>
Download mbox | patch
Permalink /patch/70576/
State New
Headers show

Comments

Dodji Seketeli - Nov. 9, 2010, 9:28 p.m.
I looked at this as well and I came up with another candidate
patch so I thought I'd post it as well.

At some point modified_type_die is called for volatile_const_my_int with
is_volatile and is_const_type set to 0, meaning we want to emit the DIE
of the cv-unqualified version of volatile_const_my_int i.e, my_int.

The problem is that the line

  /* See if we already have the appropriately qualified variant of
     this type.  */
  qualified_type
    = get_qualified_type (type,
              ((is_const_type ? TYPE_QUAL_CONST : 0)
               | (is_volatile_type ? TYPE_QUAL_VOLATILE : 0)));

fails to give us the the my_int (cv-unqualified version of
volatile_const_my_int) we want and returns NULL instead. That's because
get_qualified_type doesn't look through typedefs as it must preserve
TYPE_NAMEs (see the comment in get_qualified_type). From that point on,
I think we are likely to loose.

The patch below tries harder to come up with the cv-unqualified version
of the input type.

Fully bootstrapped and tested on x86-unknown-linux-gnu against trunk.

Patch

diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 9bb569b..f639e24 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -12715,6 +12715,19 @@  modified_type_die (tree type, int is_const_type, int is_volatile_type,
 			  ((is_const_type ? TYPE_QUAL_CONST : 0)
 			   | (is_volatile_type ? TYPE_QUAL_VOLATILE : 0)));
 
+  /* If TYPE is a typedef and we want its cv-unqualified version,
+     get_qualified_type just returns NULL because it doesn't look
+     through typedefs; In that case, let's use the underlying type of
+     the typedef.  */
+  if (qualified_type == NULL
+      && typedef_variant_p (type)
+      && (is_const_type < TYPE_READONLY (type)
+	  || is_volatile_type < TYPE_VOLATILE (type)))
+    qualified_type =
+      get_qualified_type (DECL_ORIGINAL_TYPE (TYPE_NAME (type)),
+			  ((is_const_type ? TYPE_QUAL_CONST : 0)
+			   | (is_volatile_type ? TYPE_QUAL_VOLATILE : 0)));
+
   if (qualified_type == sizetype
       && TYPE_NAME (qualified_type)
       && TREE_CODE (TYPE_NAME (qualified_type)) == TYPE_DECL)
diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/pr45997-1.C b/gcc/testsuite/g++.dg/debug/dwarf2/pr45997-1.C
new file mode 100644
index 0000000..72f24ad
--- /dev/null
+++ b/gcc/testsuite/g++.dg/debug/dwarf2/pr45997-1.C
@@ -0,0 +1,22 @@ 
+// PR debug/45997
+// { dg-do compile }
+// { dg-options "-gdwarf-2 -dA" }
+
+typedef int my_int;
+typedef const my_int const_my_int;
+typedef volatile const_my_int volatile_const_my_int;
+
+my_int v_my_int = 0;
+const_my_int v_const_my_int = 1;
+volatile_const_my_int v_volatile_const_my_int = 4;
+
+int
+main ()
+{
+  asm volatile ("" : : "r" (&v_my_int));
+  asm volatile ("" : : "r" (&v_const_my_int));
+  asm volatile ("" : : "r" (&v_volatile_const_my_int));
+  return 0;
+}
+
+// { dg-final { scan-assembler-times "DIE\[^\n\r\]*DW_TAG_base_type" 1 } }
diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/pr45997-2.C b/gcc/testsuite/g++.dg/debug/dwarf2/pr45997-2.C
new file mode 100644
index 0000000..ade5428
--- /dev/null
+++ b/gcc/testsuite/g++.dg/debug/dwarf2/pr45997-2.C
@@ -0,0 +1,22 @@ 
+// PR debug/45997
+// { dg-do compile }
+// { dg-options "-gdwarf-2 -dA" }
+
+typedef int my_int;
+typedef volatile my_int volatile_my_int;
+typedef const volatile_my_int const_volatile_my_int;
+
+my_int v_my_int = 0;
+volatile_my_int v_volatile_my_int = 1;
+const_volatile_my_int v_const_volatile_my_int = 4;
+
+int
+main ()
+{
+  asm volatile ("" : : "r" (&v_my_int));
+  asm volatile ("" : : "r" (&v_volatile_my_int));
+  asm volatile ("" : : "r" (&v_const_volatile_my_int));
+  return 0;
+}
+
+// { dg-final { scan-assembler-times "DIE\[^\n\r\]*DW_TAG_base_type" 1 } }