A::A names the constructor, but you can't call the constructor
directly, you should just write A(args).  Our error recovery was
failing in a template because we'd wrapped the arguments with
NON_DEPENDENT_EXPR, and then kept the result as part of the template
tree, whereas we're supposed to throw away anything containing
NON_DEPENDENT_EXPR once we've used it to determine types.

Tested x86_64-pc-linux-gnu, applying to trunk.
commit 4fde624556763974da407ffcf9858d5126730646
Author: Jason Merrill <ja...@redhat.com>
Date:   Mon Apr 9 15:16:32 2018 -0400

            PR c++/85262 - ICE with redundant qualification on constructor.
    
            * call.c (build_new_method_call_1): Move make_args_non_dependent
            after A::A() handling.

diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index b22a3cc132e..f978ea73f3d 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -9104,14 +9104,6 @@ build_new_method_call_1 (tree instance, tree fns, vec<tree, va_gc> **args,
   basetype = TYPE_MAIN_VARIANT (TREE_TYPE (instance));
   gcc_assert (CLASS_TYPE_P (basetype));
 
-  if (processing_template_decl)
-    {
-      orig_args = args == NULL ? NULL : make_tree_vector_copy (*args);
-      instance = build_non_dependent_expr (instance);
-      if (args != NULL)
-	make_args_non_dependent (*args);
-    }
-
   user_args = args == NULL ? NULL : *args;
   /* Under DR 147 A::A() is an invalid constructor call,
      not a functional cast.  */
@@ -9132,12 +9124,21 @@ build_new_method_call_1 (tree instance, tree fns, vec<tree, va_gc> **args,
       return call;
     }
 
+  if (processing_template_decl)
+    {
+      orig_args = args == NULL ? NULL : make_tree_vector_copy (*args);
+      instance = build_non_dependent_expr (instance);
+      if (args != NULL)
+	make_args_non_dependent (*args);
+    }
+
   /* Process the argument list.  */
   if (args != NULL && *args != NULL)
     {
       *args = resolve_args (*args, complain);
       if (*args == NULL)
 	return error_mark_node;
+      user_args = *args;
     }
 
   /* Consider the object argument to be used even if we end up selecting a
diff --git a/gcc/testsuite/g++.dg/parse/ctor10.C b/gcc/testsuite/g++.dg/parse/ctor10.C
new file mode 100644
index 00000000000..99d3ca8c18d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/ctor10.C
@@ -0,0 +1,14 @@
+// PR c++/85262
+// { dg-options -fpermissive }
+
+struct A {};
+
+template<int> struct B : A
+{
+  B()
+  {
+    A::A(A());			// { dg-warning "constructor" }
+  }
+};
+
+B<0> b;

Reply via email to