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:
parent
a7d47f3526
commit
20f058d098
8 changed files with 109 additions and 7 deletions
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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. */
|
||||
|
|
28
gcc/testsuite/g++.dg/cpp0x/pr78771-new.C
Normal file
28
gcc/testsuite/g++.dg/cpp0x/pr78771-new.C
Normal 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) {}
|
28
gcc/testsuite/g++.dg/cpp0x/pr78771-old.C
Normal file
28
gcc/testsuite/g++.dg/cpp0x/pr78771-old.C
Normal 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) {}
|
27
gcc/testsuite/g++.dg/cpp1z/pr78771.C
Normal file
27
gcc/testsuite/g++.dg/cpp1z/pr78771.C
Normal 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) {}
|
Loading…
Add table
Reference in a new issue