re PR c++/54744 (internal compiler error: Segmentation fault, by dependent base,...
authorJason Merrill <jason@redhat.com>
Thu, 6 Dec 2012 20:21:08 +0000 (15:21 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Thu, 6 Dec 2012 20:21:08 +0000 (15:21 -0500)
PR c++/54744
* pt.c (resolve_typename_type): Check TYPENAME_IS_RESOLVING_P on scope.
* init.c (expand_member_init): Check for being in a template first.
* parser.c (cp_parser_mem_initializer_list): Only check class types
for equivalence to the current class.

From-SVN: r194267

gcc/cp/ChangeLog
gcc/cp/init.c
gcc/cp/parser.c
gcc/cp/pt.c
gcc/testsuite/g++.dg/template/meminit3.C [new file with mode: 0644]

index 28f8c674d76e461fd8e15f55ead0499418a46f11..bcad0c24636bf2678113cae9f1557ea2890a746f 100644 (file)
@@ -1,5 +1,11 @@
 2012-12-06  Jason Merrill  <jason@redhat.com>
 
+       PR c++/54744
+       * pt.c (resolve_typename_type): Check TYPENAME_IS_RESOLVING_P on scope.
+       * init.c (expand_member_init): Check for being in a template first.
+       * parser.c (cp_parser_mem_initializer_list): Only check class types
+       for equivalence to the current class.
+
        PR c++/54913
        * semantics.c (finish_qualified_id_expr): convert_from_reference
        after building a SCOPE_REF.
index 76a31c1becf071a4f3b281957c3de8c21b4cae86..2206c169bec214974c9e51510beee87599f6de98 100644 (file)
@@ -1370,8 +1370,8 @@ expand_member_init (tree name)
       tree virtual_binfo;
       int i;
 
-      if (same_type_p (basetype, current_class_type)
-         || current_template_parms)
+      if (current_template_parms
+         || same_type_p (basetype, current_class_type))
          return basetype;
 
       class_binfo = TYPE_BINFO (current_class_type);
index a010f1fb30588e813657cf7f6ef99ae2fb3aaba8..3566d741f14c7b3a2f294f6c6b57eebc4e35170f 100644 (file)
@@ -11592,7 +11592,7 @@ cp_parser_mem_initializer_list (cp_parser* parser)
        }
       /* Look for a target constructor. */
       if (mem_initializer != error_mark_node
-         && TYPE_P (TREE_PURPOSE (mem_initializer))
+         && CLASS_TYPE_P (TREE_PURPOSE (mem_initializer))
          && same_type_p (TREE_PURPOSE (mem_initializer), current_class_type))
        {
          maybe_warn_cpp0x (CPP0X_DELEGATING_CTORS);
index 8b0ead1700b4a21202d737d9d222198eda5657f4..87cd33760c251bfa483918c9c6ce559cf97a4e20 100644 (file)
@@ -20079,7 +20079,16 @@ resolve_typename_type (tree type, bool only_current_p)
   /* If the SCOPE is itself a TYPENAME_TYPE, then we need to resolve
      it first before we can figure out what NAME refers to.  */
   if (TREE_CODE (scope) == TYPENAME_TYPE)
-    scope = resolve_typename_type (scope, only_current_p);
+    {
+      if (TYPENAME_IS_RESOLVING_P (scope))
+       /* Given a class template A with a dependent base with nested type C,
+          typedef typename A::C::C C will land us here, as trying to resolve
+          the initial A::C leads to the local C typedef, which leads back to
+          A::C::C.  So we break the recursion now.  */
+       return type;
+      else
+       scope = resolve_typename_type (scope, only_current_p);
+    }
   /* If we don't know what SCOPE refers to, then we cannot resolve the
      TYPENAME_TYPE.  */
   if (TREE_CODE (scope) == TYPENAME_TYPE)
diff --git a/gcc/testsuite/g++.dg/template/meminit3.C b/gcc/testsuite/g++.dg/template/meminit3.C
new file mode 100644 (file)
index 0000000..b682449
--- /dev/null
@@ -0,0 +1,12 @@
+// PR c++/54744
+
+template <typename T>
+struct base {
+  typedef base base_type;
+};
+
+template <typename T>
+struct derived : base<T> {
+  typedef typename derived::base_type::base_type base_type;
+  derived() : base_type() {}
+};