[except.spec] says that "In a noexcept-specifier, the constant-expression, if supplied, shall be a contextually converted constant expression of type bool". We now have a dedicated function for creating such an expression, so build_noexcept_spec should make use of it.
As a consequence, we now reject pr86397-2.C but that's correct: converting a pointer to bool is a "boolean conversion", which is not allowed under the rules for a converted constant expression ([expr.const]p7). Bootstrapped/regtested on x86_64-linux, ok for trunk? 2019-04-11 Marek Polacek <pola...@redhat.com> * except.c (build_noexcept_spec): Use build_converted_constant_bool_expr instead of perform_implicit_conversion_flags. * g++.dg/cpp0x/noexcept30.C: Tweak dg-error. * g++.dg/cpp0x/pr86397-1.C: Likewise. * g++.dg/cpp0x/pr86397-2.C: Likewise. diff --git gcc/cp/except.c gcc/cp/except.c index 40e973fad66..25ab8699589 100644 --- gcc/cp/except.c +++ gcc/cp/except.c @@ -1285,9 +1285,7 @@ build_noexcept_spec (tree expr, tsubst_flags_t complain) if (TREE_CODE (expr) != DEFERRED_NOEXCEPT && !value_dependent_expression_p (expr)) { - expr = perform_implicit_conversion_flags (boolean_type_node, expr, - complain, - LOOKUP_NORMAL); + expr = build_converted_constant_bool_expr (expr, complain); expr = instantiate_non_dependent_expr (expr); expr = cxx_constant_value (expr); } diff --git gcc/testsuite/g++.dg/cpp0x/noexcept30.C gcc/testsuite/g++.dg/cpp0x/noexcept30.C index 8c7ff2aad45..6a9f7821092 100644 --- gcc/testsuite/g++.dg/cpp0x/noexcept30.C +++ gcc/testsuite/g++.dg/cpp0x/noexcept30.C @@ -5,7 +5,7 @@ template<typename A> struct F { template<typename B> - void f() noexcept(&F::template f<B>) {} // { dg-error "exception specification" } + void f() noexcept(&F::template f<B>) {} // { dg-error "exception specification|convert" } }; int main () { diff --git gcc/testsuite/g++.dg/cpp0x/pr86397-1.C gcc/testsuite/g++.dg/cpp0x/pr86397-1.C index a0123cba0da..c6cfc1b5561 100644 --- gcc/testsuite/g++.dg/cpp0x/pr86397-1.C +++ gcc/testsuite/g++.dg/cpp0x/pr86397-1.C @@ -1,5 +1,5 @@ // { dg-do compile { target c++11 } } // { dg-options "-fdelete-null-pointer-checks" } void e(); -template <bool> void f(int() noexcept(e)) {} -template void f<false>(int()); // { dg-error "does not match" "" { target c++17 } } +template <bool> void f(int() noexcept(e)) {} // { dg-error "convert" } +template void f<false>(int()); diff --git gcc/testsuite/g++.dg/cpp0x/pr86397-2.C gcc/testsuite/g++.dg/cpp0x/pr86397-2.C index 8e4956bcf6c..54aefdb0916 100644 --- gcc/testsuite/g++.dg/cpp0x/pr86397-2.C +++ gcc/testsuite/g++.dg/cpp0x/pr86397-2.C @@ -1,5 +1,5 @@ // { dg-do compile { target c++11 } } // { dg-options "-fdelete-null-pointer-checks" } void e(); -template <bool> void f(int() noexcept(e)) {} -template void f<false>(int() noexcept); +template <bool> void f(int() noexcept(e)) {} // { dg-error "convert" } +template void f<false>(int() noexcept); // { dg-error "does not match any template declaration" "" { target c++17 } }