From 20f058d0986d8e7f81c1e45217b6d4c361dc089b Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Fri, 27 Jan 2017 11:48:34 -0500 Subject: [PATCH] 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 --- gcc/cp/ChangeLog | 9 ++++++++ gcc/cp/call.c | 6 +++++ gcc/cp/class.c | 2 -- gcc/cp/method.c | 14 +++++++++--- gcc/cp/pt.c | 2 -- gcc/testsuite/g++.dg/cpp0x/pr78771-new.C | 28 ++++++++++++++++++++++++ gcc/testsuite/g++.dg/cpp0x/pr78771-old.C | 28 ++++++++++++++++++++++++ gcc/testsuite/g++.dg/cpp1z/pr78771.C | 27 +++++++++++++++++++++++ 8 files changed, 109 insertions(+), 7 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/pr78771-new.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/pr78771-old.C create mode 100644 gcc/testsuite/g++.dg/cpp1z/pr78771.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 406d382135f..1f31731bc69 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,12 @@ +2017-01-27 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. + 2017-01-27 Adam Butcher PR c++/64382 diff --git a/gcc/cp/call.c b/gcc/cp/call.c index a78e1a9c8a2..8030d7ebb0b 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -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; diff --git a/gcc/cp/class.c b/gcc/cp/class.c index b7c26a1829f..03a973084e5 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -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; } diff --git a/gcc/cp/method.c b/gcc/cp/method.c index 5b366f0e960..e80b80606b5 100644 --- a/gcc/cp/method.c +++ b/gcc/cp/method.c @@ -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); diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 57334b4c44e..0ba95d636cd 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -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. */ diff --git a/gcc/testsuite/g++.dg/cpp0x/pr78771-new.C b/gcc/testsuite/g++.dg/cpp0x/pr78771-new.C new file mode 100644 index 00000000000..f489f8631f4 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/pr78771-new.C @@ -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 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) {} diff --git a/gcc/testsuite/g++.dg/cpp0x/pr78771-old.C b/gcc/testsuite/g++.dg/cpp0x/pr78771-old.C new file mode 100644 index 00000000000..b723b1188db --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/pr78771-old.C @@ -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 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) {} diff --git a/gcc/testsuite/g++.dg/cpp1z/pr78771.C b/gcc/testsuite/g++.dg/cpp1z/pr78771.C new file mode 100644 index 00000000000..91784948d16 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1z/pr78771.C @@ -0,0 +1,27 @@ +// PR c++/78771 +// { dg-options -std=c++1z } + +// ICE instantiating a deleted inherited ctor + +struct Base +{ + template 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) {} -- 2.30.2