Commit 20f058d0 by Jason Merrill Committed by Jason Merrill

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
parent a7d47f35
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> 2017-01-27 Adam Butcher <adam@jessamine.co.uk>
PR c++/64382 PR c++/64382
......
...@@ -7581,6 +7581,12 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain) ...@@ -7581,6 +7581,12 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
joust (cand, w->loser, 1, 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. */ /* Make =delete work with SFINAE. */
if (DECL_DELETED_FN (fn) && !(complain & tf_error)) if (DECL_DELETED_FN (fn) && !(complain & tf_error))
return error_mark_node; return error_mark_node;
......
...@@ -1197,8 +1197,6 @@ add_method (tree type, tree method, tree using_decl) ...@@ -1197,8 +1197,6 @@ add_method (tree type, tree method, tree using_decl)
SET_DECL_INHERITED_CTOR SET_DECL_INHERITED_CTOR
(fn, ovl_cons (DECL_INHERITED_CTOR (method), (fn, ovl_cons (DECL_INHERITED_CTOR (method),
DECL_INHERITED_CTOR (fn))); DECL_INHERITED_CTOR (fn)));
/* Adjust deletedness and such. */
deduce_inheriting_ctor (fn);
/* And discard the new one. */ /* And discard the new one. */
return false; return false;
} }
......
...@@ -1855,6 +1855,7 @@ explain_implicit_non_constexpr (tree decl) ...@@ -1855,6 +1855,7 @@ explain_implicit_non_constexpr (tree decl)
void void
deduce_inheriting_ctor (tree decl) deduce_inheriting_ctor (tree decl)
{ {
decl = DECL_ORIGIN (decl);
gcc_assert (DECL_INHERITED_CTOR (decl)); gcc_assert (DECL_INHERITED_CTOR (decl));
tree spec; tree spec;
bool trivial, constexpr_, deleted; bool trivial, constexpr_, deleted;
...@@ -1868,6 +1869,13 @@ deduce_inheriting_ctor (tree decl) ...@@ -1868,6 +1869,13 @@ deduce_inheriting_ctor (tree decl)
deleted = true; deleted = true;
DECL_DELETED_FN (decl) = deleted; DECL_DELETED_FN (decl) = deleted;
TREE_TYPE (decl) = build_exception_variant (TREE_TYPE (decl), spec); 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 /* Implicitly declare the special function indicated by KIND, as a
...@@ -1968,10 +1976,10 @@ implicitly_declare_fn (special_function_kind kind, tree type, ...@@ -1968,10 +1976,10 @@ implicitly_declare_fn (special_function_kind kind, tree type,
bool trivial_p = false; 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 /* For an inheriting constructor, just copy these flags from the
the inherited constructor template for now. */ inherited constructor until deduce_inheriting_ctor. */
raises = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (inherited_ctor)); raises = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (inherited_ctor));
deleted_p = DECL_DELETED_FN (inherited_ctor); deleted_p = DECL_DELETED_FN (inherited_ctor);
constexpr_p = DECL_DECLARED_CONSTEXPR_P (inherited_ctor); constexpr_p = DECL_DECLARED_CONSTEXPR_P (inherited_ctor);
......
...@@ -12358,8 +12358,6 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) ...@@ -12358,8 +12358,6 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
maybe_retrofit_in_chrg (r); maybe_retrofit_in_chrg (r);
if (DECL_CONSTRUCTOR_P (r)) if (DECL_CONSTRUCTOR_P (r))
grok_ctor_properties (ctx, 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 this is an instantiation of a member template, clone it.
If it isn't, that'll be handled by If it isn't, that'll be handled by
clone_constructors_and_destructors. */ clone_constructors_and_destructors. */
......
// 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) {}
// 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) {}
// 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) {}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment