2017-01-11 Nathan Sidwell <nathan@acm.org>
PR c++/78771
* pt.c (instantiate_template_1): Check for recursive instantiation
of inheriting constructor when not new-inheriting-ctor.
* method.c (deduce_inheriting_ctor): Use originating ctor when
new-inheriting-ctor.
PR c++/78771
* g++.dg/cpp0x/pr78771-old.C: New.
* g++.dg/cpp0x/pr78771-new.C: New.
* g++.dg/cpp1z/pr78771.C: New.
===================================================================
@@ -1858,11 +1858,15 @@ deduce_inheriting_ctor (tree decl)
gcc_assert (DECL_INHERITED_CTOR (decl));
tree spec;
bool trivial, constexpr_, deleted;
+
+ tree inherited = DECL_INHERITED_CTOR (decl);
+ if (flag_new_inheriting_ctors)
+ inherited = strip_inheriting_ctors (inherited);
+
synthesized_method_walk (DECL_CONTEXT (decl), sfk_inheriting_constructor,
false, &spec, &trivial, &deleted, &constexpr_,
- /*diag*/false,
- DECL_INHERITED_CTOR (decl),
- FUNCTION_FIRST_USER_PARMTYPE (decl));
+ /*diag=*/false,
+ inherited, FUNCTION_FIRST_USER_PARMTYPE (decl));
if (TREE_CODE (inherited_ctor_binfo (decl)) != TREE_BINFO)
/* Inherited the same constructor from different base subobjects. */
deleted = true;
===================================================================
@@ -17963,10 +17963,22 @@ instantiate_template_1 (tree tmpl, tree
if (spec == error_mark_node)
return error_mark_node;
+ /* If this is an inherited ctor, we can recursively clone it
+ when deducing the validity of the ctor. But we won't have
+ cloned the function yet, so do it now. We'll redo this
+ later, but any recursive information learnt here can't
+ change the validity. */
+ if (!TREE_CHAIN (spec))
+ {
+ gcc_assert (!flag_new_inheriting_ctors
+ && DECL_INHERITED_CTOR (spec));
+ clone_function_decl (spec, /*update_method_vec_p=*/0);
+ }
/* Look for the clone. */
FOR_EACH_CLONE (clone, spec)
if (DECL_NAME (clone) == DECL_NAME (tmpl))
return clone;
+
/* We should always have found the clone by now. */
gcc_unreachable ();
return NULL_TREE;
===================================================================
@@ -0,0 +1,28 @@
+// PR c++/78771
+// { dg-do compile { target c++11 } }
+// { dg-additional-options "-fnew-inheriting-ctors" }
+
+// ICE instantiating a deleted inherited ctor
+
+struct Base
+{
+ template <typename U> Base (U);
+
+ Base (int);
+};
+
+struct Derived;
+
+struct Middle : Base
+{
+ using Base::Base;
+
+ Middle (Derived);
+};
+
+struct Derived : Middle
+{
+ using Middle::Middle;
+};
+
+Middle::Middle (Derived) : Middle (0) {}
===================================================================
@@ -0,0 +1,28 @@
+// PR c++/78771
+// { dg-do compile { target c++11 } }
+// { dg-additional-options "-fno-new-inheriting-ctors" }
+
+// ICE instantiating a deleted inherited ctor
+
+struct Base
+{
+ template <typename U> Base (U);
+
+ Base (int);
+};
+
+struct Derived;
+
+struct Middle : Base
+{
+ using Base::Base;
+
+ Middle (Derived);
+};
+
+struct Derived : Middle
+{
+ using Middle::Middle;
+};
+
+Middle::Middle (Derived) : Middle (0) {}
===================================================================
@@ -0,0 +1,27 @@
+// PR c++/78771
+// { dg-options -std=c++1z }
+
+// ICE instantiating a deleted inherited ctor
+
+struct Base
+{
+ template <typename U> Base (U);
+
+ Base (int);
+};
+
+struct Derived;
+
+struct Middle : Base
+{
+ using Base::Base;
+
+ Middle (Derived);
+};
+
+struct Derived : Middle
+{
+ using Middle::Middle;
+};
+
+Middle::Middle (Derived) : Middle (0) {}