Since my patch for 81359 allowed us to signal failure on return from maybe_instantiate_noexcept, we no longer need to turn an error into noexcept(false). We also need to handle NSDMI instantiation errors under synthesized_method_walk. This change caused some instantiation context notes to be lost in the testsuite, so I added push_tinst_level to get_defaulted_eh_spec to restore that context.
Tested x86_64-pc-linux-gnu, applying to trunk. * method.c (walk_field_subobs): Remember errors from get_nsdmi. (get_defaulted_eh_spec): Call push_tinst_level. * pt.c (maybe_instantiate_noexcept): Keep error_mark_node. * typeck2.c (merge_exception_specifiers): Handle error_mark_node. --- gcc/cp/method.c | 10 +++++++++- gcc/cp/pt.c | 2 -- gcc/cp/typeck2.c | 3 +++ gcc/testsuite/g++.dg/cpp0x/nsdmi3.C | 3 ++- gcc/testsuite/g++.dg/ext/is_constructible3.C | 17 +++++++++++++++++ gcc/cp/ChangeLog | 8 ++++++++ 6 files changed, 39 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/g++.dg/ext/is_constructible3.C diff --git a/gcc/cp/method.c b/gcc/cp/method.c index a5f2304d49c..6e0df68273e 100644 --- a/gcc/cp/method.c +++ b/gcc/cp/method.c @@ -1367,7 +1367,10 @@ walk_field_subobs (tree fields, special_function_kind sfk, tree fnname, if (spec_p) { tree nsdmi = get_nsdmi (field, /*ctor*/false, complain); - if (!expr_noexcept_p (nsdmi, complain)) + if (nsdmi == error_mark_node) + *spec_p = error_mark_node; + else if (*spec_p != error_mark_node + && !expr_noexcept_p (nsdmi, complain)) *spec_p = noexcept_false_spec; } /* Don't do the normal processing. */ @@ -1753,8 +1756,13 @@ get_defaulted_eh_spec (tree decl, tsubst_flags_t complain) if (SFK_DTOR_P (sfk) && DECL_VIRTUAL_P (decl)) /* We have to examine virtual bases even if abstract. */ sfk = sfk_virtual_destructor; + bool pushed = false; + if (CLASSTYPE_TEMPLATE_INSTANTIATION (ctype)) + pushed = push_tinst_level (decl); synthesized_method_walk (ctype, sfk, const_p, &spec, NULL, NULL, NULL, diag, &inh, parms); + if (pushed) + pop_tinst_level (); return spec; } diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index d8be92ddca4..a69a17ad3b2 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -24199,8 +24199,6 @@ maybe_instantiate_noexcept (tree fn, tsubst_flags_t complain) pop_deferring_access_checks (); pop_access_scope (fn); pop_tinst_level (); - if (spec == error_mark_node) - spec = noexcept_false_spec; } else spec = noexcept_false_spec; diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c index ac2c253196b..4e4b1f03b7c 100644 --- a/gcc/cp/typeck2.c +++ b/gcc/cp/typeck2.c @@ -2363,6 +2363,9 @@ merge_exception_specifiers (tree list, tree add) { tree noex, orig_list; + if (list == error_mark_node || add == error_mark_node) + return error_mark_node; + /* No exception-specifier or noexcept(false) are less strict than anything else. Prefer the newer variant (LIST). */ if (!list || list == noexcept_false_spec) diff --git a/gcc/testsuite/g++.dg/cpp0x/nsdmi3.C b/gcc/testsuite/g++.dg/cpp0x/nsdmi3.C index d2e74392487..8276eab8f80 100644 --- a/gcc/testsuite/g++.dg/cpp0x/nsdmi3.C +++ b/gcc/testsuite/g++.dg/cpp0x/nsdmi3.C @@ -13,6 +13,7 @@ struct B A a3 = { 3 }; // { dg-error "explicit" } }; -constexpr B b; // { dg-error "B::B" } +constexpr B b; +// { dg-prune-output "B::B. is not usable" } // { dg-prune-output "B::a1" } diff --git a/gcc/testsuite/g++.dg/ext/is_constructible3.C b/gcc/testsuite/g++.dg/ext/is_constructible3.C new file mode 100644 index 00000000000..c7c58746cd0 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/is_constructible3.C @@ -0,0 +1,17 @@ +// PR c++/88368 +// { dg-do compile { target c++11 } } + +struct A { + + struct B { + int I = 1; + B() = default; + }; + + static constexpr bool v = __is_constructible (B); + +}; + +void print() { + A::B BB; +} diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 9c42190f04a..3fe0cedb0e3 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,11 @@ +2019-02-19 Jason Merrill <ja...@redhat.com> + + PR c++/88368 - wrong 'use of deleted function' + * method.c (walk_field_subobs): Remember errors from get_nsdmi. + (get_defaulted_eh_spec): Call push_tinst_level. + * pt.c (maybe_instantiate_noexcept): Keep error_mark_node. + * typeck2.c (merge_exception_specifiers): Handle error_mark_node. + 2019-02-19 Chung-Lin Tang <clt...@codesourcery.com> PR c/87924 base-commit: cfa86c5ebc839435491f6ab8f541eb44f02d6849 -- 2.20.1