diff mbox

Fix c++/47291

Message ID m37he1cjjd.fsf@redhat.com
State New
Headers show

Commit Message

Dodji Seketeli Jan. 19, 2011, 9:47 a.m. UTC
Hello,

Consider this example:

 struct S;
 template< int S::* cst> struct D {};

 struct S
 {
   int i;
   D< &S::i> di; // #0 <-- folding &S::i is failing
		 // because i has no offset as S is not laid out yet
 };

While generating debug info for the template parameter and argument of
D<&S::i> we fail to fold &S::i because as S is not laid out yet, i has
no offset.

Following the offline discussion we had about this, the patch below
waits until the end of the compilation [so all types are laid out] of
the CU to generate debug info of template parameters for types that
are instances of templates.

Tested on x86_64-unknown-linux-gnu against trunk.

From 5d2480460cb004cd19355eac37b1a11715efdcad Mon Sep 17 00:00:00 2001
From: Dodji Seketeli <dodji@redhat.com>
Date: Tue, 18 Jan 2011 11:32:43 +0100
Subject: [PATCH] Fix PR c++/47291

gcc/
	PR c++/47291
	* dwarf2out.c (generic_type_p, schedule_generic_params_dies_gen)
	(gen_scheduled_generic_parms_dies): New functions.
	(gen_struct_or_union_type_die): Schedule template parameters DIEs
	generation for the end of CU compilation.
	(dwarf2out_finish): Generate template parameters DIEs here.

gcc/testsuite/

	PR c++/47291
	* g++.dg/debug/dwarf2/template-params-10.C: New test.
---
 gcc/dwarf2out.c                                    |   57 +++++++++++++++++++-
 .../g++.dg/debug/dwarf2/template-params-10.C       |   22 ++++++++
 2 files changed, 78 insertions(+), 1 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/debug/dwarf2/template-params-10.C

Comments

Jason Merrill Jan. 19, 2011, 3:25 p.m. UTC | #1
OK.

Jason
diff mbox

Patch

diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index ca17967..ffec446 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -6196,6 +6196,12 @@  static GTY(()) struct dwarf_file_data * file_table_last_lookup;
 
 static GTY(()) VEC(die_arg_entry,gc) *tmpl_value_parm_die_table;
 
+/* Instances of generic types for which we need to generate debug
+   info that describe their generic parameters and arguments. That
+   generation needs to happen once all types are properly laid out so
+   we do it at the end of compilation.  */
+static GTY(()) VEC(tree,gc) *generic_type_instances;
+
 /* Offset from the "steady-state frame pointer" to the frame base,
    within the current function.  */
 static HOST_WIDE_INT frame_pointer_fb_offset;
@@ -6490,6 +6496,9 @@  static inline void add_AT_vms_delta (dw_die_ref, enum dwarf_attribute,
 				     const char *, const char *);
 static void append_entry_to_tmpl_value_parm_die_table (dw_die_ref, tree);
 static void gen_remaining_tmpl_value_param_die_attribute (void);
+static bool generic_type_p (tree);
+static void schedule_generic_params_dies_gen (tree t);
+static void gen_scheduled_generic_parms_dies (void);
 
 /* Section names used to hold DWARF debugging information.  */
 #ifndef DEBUG_INFO_SECTION
@@ -20147,7 +20156,7 @@  gen_struct_or_union_type_die (tree type, dw_die_ref context_die,
   /* Generate child dies for template paramaters.  */
   if (debug_info_level > DINFO_LEVEL_TERSE
       && COMPLETE_TYPE_P (type))
-    gen_generic_params_dies (type);
+    schedule_generic_params_dies_gen (type);
 
   /* If this type has been completed, then give it a byte_size attribute and
      then give a list of members.  */
@@ -21574,6 +21583,33 @@  append_entry_to_tmpl_value_parm_die_table (dw_die_ref die, tree arg)
 		 &entry);
 }
 
+/* Return TRUE if T is an instance of generic type, FALSE
+   otherwise.  */
+
+static bool
+generic_type_p (tree t)
+{
+  if (t == NULL_TREE || !TYPE_P (t))
+    return false;
+  return lang_hooks.get_innermost_generic_parms (t) != NULL_TREE;
+}
+
+/* Schedule the generation of the generic parameter dies for the
+  instance of generic type T. The proper generation itself is later done by
+  gen_scheduled_generic_parms_dies. */
+
+static void
+schedule_generic_params_dies_gen (tree t)
+{
+  if (!generic_type_p (t))
+    return;
+
+  if (generic_type_instances == NULL)
+    generic_type_instances = VEC_alloc (tree, gc, 256);
+
+  VEC_safe_push (tree, gc, generic_type_instances, t);
+}
+
 /* Add a DW_AT_const_value attribute to DIEs that were scheduled
    by append_entry_to_tmpl_value_parm_die_table. This function must
    be called after function DIEs have been generated.  */
@@ -21591,6 +21627,24 @@  gen_remaining_tmpl_value_param_die_attribute (void)
     }
 }
 
+/* Generate generic parameters DIEs for instances of generic types
+   that have been previously scheduled by
+   schedule_generic_params_dies_gen. This function must be called
+   after all the types of the CU have been laid out.  */
+
+static void
+gen_scheduled_generic_parms_dies (void)
+{
+  unsigned i;
+  tree t;
+
+  if (generic_type_instances == NULL)
+    return;
+  
+  FOR_EACH_VEC_ELT (tree, generic_type_instances, i, t)
+    gen_generic_params_dies (t);
+}
+
 
 /* Replace DW_AT_name for the decl with name.  */
 
@@ -23153,6 +23207,7 @@  dwarf2out_finish (const char *filename)
   htab_t comdat_type_table;
   unsigned int i;
 
+  gen_scheduled_generic_parms_dies ();
   gen_remaining_tmpl_value_param_die_attribute ();
 
   /* Add the name for the main input file now.  We delayed this from
diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/template-params-10.C b/gcc/testsuite/g++.dg/debug/dwarf2/template-params-10.C
new file mode 100644
index 0000000..c12fe39
--- /dev/null
+++ b/gcc/testsuite/g++.dg/debug/dwarf2/template-params-10.C
@@ -0,0 +1,22 @@ 
+// Origin PR c++/47291
+// { dg-options "-g -dA" }
+// { dg-do compile }
+
+struct S;
+template< int S::* cst> struct D {};
+
+struct S
+{
+  int i;
+  D < &S::i > di; //<-- folding &S::i was failing
+                  // because i has no offset as S is not laid out yet
+};
+
+int
+main()
+{
+  S s;
+  return s.i;
+}
+
+// { dg-final { scan-assembler-times "DIE \\(\[^\n\r\]*\\) DW_TAG_template_value_param" 1 } }