[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 } }

Reply via email to