As PR67371 shows gcc currently rejects all throw statements in constant-expressions, even when they are never executed.
Fix by simply allowing THROW_EXPR in potential_constant_expression_1. One drawback is that we now accept some ill formed cases, but they fall under the "no diagnostic required" rule in the standard, e.g.: constexpr int f1() { throw; return 0; } or constexpr void f2() { throw; } Tested on ppc64le. OK for trunk? Thanks. PR c++/67371 * constexpr.c (potential_constant_expression_1): Allow THROW_EXPR. diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index 1eacb8be9a44..34c503ab2bc4 100644 --- a/gcc/cp/constexpr.c +++ b/gcc/cp/constexpr.c @@ -4043,6 +4043,7 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, case BREAK_STMT: case CONTINUE_STMT: case REQUIRES_EXPR: + case THROW_EXPR: return true; case AGGR_INIT_EXPR: @@ -4324,7 +4325,6 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, case VEC_NEW_EXPR: case DELETE_EXPR: case VEC_DELETE_EXPR: - case THROW_EXPR: case OMP_ATOMIC: case OMP_ATOMIC_READ: case OMP_ATOMIC_CAPTURE_OLD: diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-throw.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-throw.C new file mode 100644 index 000000000000..09a3e618f8a2 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-throw.C @@ -0,0 +1,17 @@ +// { dg-do compile { target c++14 } } +constexpr void f() { + if (false) + throw; +} + +constexpr int fun(int n) { + switch (n) { + case 0: + return 1; + default: + throw; // { dg-error "not a constant-expression" } + } +} + +static_assert(fun(0), ""); +static_assert(fun(1), ""); // { dg-error "non-constant condition" } -- Markus