re PR c++/22489 (ICE in dwarf2out_finish with using namespace in a local class and...
authorJason Merrill <jason@redhat.com>
Sun, 13 Nov 2005 07:34:50 +0000 (02:34 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Sun, 13 Nov 2005 07:34:50 +0000 (02:34 -0500)
        PR c++/22489
        * dwarf2out.c (gen_subprogram_die): Force a declaration die for
        lazily declared methods.
        (force_decl_die): Stop if forcing out the context already make a
        DIE for the decl.
        (force_type_die): Likewise.

From-SVN: r106853

gcc/ChangeLog
gcc/dwarf2out.c
gcc/testsuite/g++.dg/debug/using2.C [new file with mode: 0644]

index f7ddeff..c2932f5 100644 (file)
@@ -1,3 +1,12 @@
+2005-11-13  Jason Merrill  <jason@redhat.com>
+
+       PR c++/22489
+       * dwarf2out.c (gen_subprogram_die): Force a declaration die for
+       lazily declared methods.
+       (force_decl_die): Stop if forcing out the context already make a
+       DIE for the decl.
+       (force_type_die): Likewise.
+
 2005-11-13  Andrew Pinski  <pinskia@physics.uc.edu>
 
        PR middle-end/24820
index 28e0031..f7a006e 100644 (file)
@@ -11478,6 +11478,14 @@ gen_subprogram_die (tree decl, dw_die_ref context_die)
       gcc_assert (!old_die);
     }
 
+  /* Now that the C++ front end lazily declares artificial member fns, we
+     might need to retrofit the declaration into its class.  */
+  if (!declaration && !origin && !old_die
+      && DECL_CONTEXT (decl) && TYPE_P (DECL_CONTEXT (decl))
+      && !class_or_namespace_scope_p (context_die)
+      && debug_info_level > DINFO_LEVEL_TERSE)
+    old_die = force_decl_die (decl);
+
   if (origin != NULL)
     {
       gcc_assert (!declaration || local_scope_p (context_die));
@@ -11579,7 +11587,7 @@ gen_subprogram_die (tree decl, dw_die_ref context_die)
 
             Note that force_decl_die() forces function declaration die. It is
             later reused to represent definition.  */
-           equate_decl_number_to_die (decl, subr_die);
+         equate_decl_number_to_die (decl, subr_die);
        }
     }
   else if (DECL_ABSTRACT (decl))
@@ -12790,6 +12798,10 @@ force_decl_die (tree decl)
       else
        context_die = comp_unit_die;
 
+      decl_die = lookup_decl_die (decl);
+      if (decl_die)
+       return decl_die;
+
       switch (TREE_CODE (decl))
        {
        case FUNCTION_DECL:
@@ -12840,13 +12852,18 @@ force_type_die (tree type)
     {
       dw_die_ref context_die;
       if (TYPE_CONTEXT (type))
-       if (TYPE_P (TYPE_CONTEXT (type)))
-         context_die = force_type_die (TYPE_CONTEXT (type));
-       else
-         context_die = force_decl_die (TYPE_CONTEXT (type));
+       {
+         if (TYPE_P (TYPE_CONTEXT (type)))
+           context_die = force_type_die (TYPE_CONTEXT (type));
+         else
+           context_die = force_decl_die (TYPE_CONTEXT (type));
+       }
       else
        context_die = comp_unit_die;
 
+      type_die = lookup_type_die (type);
+      if (type_die)
+       return type_die;
       gen_type_die (type, context_die);
       type_die = lookup_type_die (type);
       gcc_assert (type_die);
diff --git a/gcc/testsuite/g++.dg/debug/using2.C b/gcc/testsuite/g++.dg/debug/using2.C
new file mode 100644 (file)
index 0000000..94f0dea
--- /dev/null
@@ -0,0 +1,21 @@
+// PR c++/22489
+
+namespace N { }
+
+struct T
+{
+  T () { }
+};
+
+void
+bar ()
+{
+  struct U : public T
+  {
+    void baz ()
+    {
+      using namespace N;
+    }
+  } u;
+  u.baz();
+}