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.

From-SVN: r244988
This commit is contained in:
Jason Merrill 2017-01-27 11:48:34 -05:00 committed by Jason Merrill
parent a7d47f3526
commit 20f058d098
8 changed files with 109 additions and 7 deletions

View file

@ -1,3 +1,12 @@
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

View file

@ -7581,6 +7581,12 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
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;

View file

@ -1197,8 +1197,6 @@ add_method (tree type, tree method, tree using_decl)
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;
}

View file

@ -1855,6 +1855,7 @@ explain_implicit_non_constexpr (tree decl)
void
deduce_inheriting_ctor (tree decl)
{
decl = DECL_ORIGIN (decl);
gcc_assert (DECL_INHERITED_CTOR (decl));
tree spec;
bool trivial, constexpr_, deleted;
@ -1868,6 +1869,13 @@ deduce_inheriting_ctor (tree decl)
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
@ -1968,10 +1976,10 @@ implicitly_declare_fn (special_function_kind kind, tree type,
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);

View file

@ -12358,8 +12358,6 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
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. */

View file

@ -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) {}

View file

@ -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) {}

View file

@ -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) {}