* call.c (build_over_call): Call deduce_inheriting_ctor here.
* pt.c (tsubst_decl): Not here.
* class.c (add_method): Or here.
* method.c (deduce_inheriting_ctor): Handle clones.
(implicitly_declare_fn): Don't deduce inheriting ctors yet.
From-SVN: r244988
+2017-01-27 Jason Merrill <jason@redhat.com>
+
+ PR c++/78771 - ICE with inherited constructor.
+ * call.c (build_over_call): Call deduce_inheriting_ctor here.
+ * pt.c (tsubst_decl): Not here.
+ * class.c (add_method): Or here.
+ * method.c (deduce_inheriting_ctor): Handle clones.
+ (implicitly_declare_fn): Don't deduce inheriting ctors yet.
+
2017-01-27 Adam Butcher <adam@jessamine.co.uk>
PR c++/64382
joust (cand, w->loser, 1, complain);
}
+ /* OK, we're actually calling this inherited constructor; set its deletedness
+ appropriately. We can get away with doing this here because calling is
+ the only way to refer to a constructor. */
+ if (DECL_INHERITED_CTOR (fn))
+ deduce_inheriting_ctor (fn);
+
/* Make =delete work with SFINAE. */
if (DECL_DELETED_FN (fn) && !(complain & tf_error))
return error_mark_node;
SET_DECL_INHERITED_CTOR
(fn, ovl_cons (DECL_INHERITED_CTOR (method),
DECL_INHERITED_CTOR (fn)));
- /* Adjust deletedness and such. */
- deduce_inheriting_ctor (fn);
/* And discard the new one. */
return false;
}
void
deduce_inheriting_ctor (tree decl)
{
+ decl = DECL_ORIGIN (decl);
gcc_assert (DECL_INHERITED_CTOR (decl));
tree spec;
bool trivial, constexpr_, deleted;
deleted = true;
DECL_DELETED_FN (decl) = deleted;
TREE_TYPE (decl) = build_exception_variant (TREE_TYPE (decl), spec);
+
+ tree clone;
+ FOR_EACH_CLONE (clone, decl)
+ {
+ DECL_DELETED_FN (clone) = deleted;
+ TREE_TYPE (clone) = build_exception_variant (TREE_TYPE (clone), spec);
+ }
}
/* Implicitly declare the special function indicated by KIND, as a
bool trivial_p = false;
- if (inherited_ctor && TREE_CODE (inherited_ctor) == TEMPLATE_DECL)
+ if (inherited_ctor)
{
- /* For an inheriting constructor template, just copy these flags from
- the inherited constructor template for now. */
+ /* For an inheriting constructor, just copy these flags from the
+ inherited constructor until deduce_inheriting_ctor. */
raises = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (inherited_ctor));
deleted_p = DECL_DELETED_FN (inherited_ctor);
constexpr_p = DECL_DECLARED_CONSTEXPR_P (inherited_ctor);
maybe_retrofit_in_chrg (r);
if (DECL_CONSTRUCTOR_P (r))
grok_ctor_properties (ctx, r);
- if (DECL_INHERITED_CTOR (r))
- deduce_inheriting_ctor (r);
/* If this is an instantiation of a member template, clone it.
If it isn't, that'll be handled by
clone_constructors_and_destructors. */
--- /dev/null
+// 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) {}
--- /dev/null
+// 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) {}
--- /dev/null
+// 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) {}