From 748c426a1b106499ced440f548743efdde564d4d Mon Sep 17 00:00:00 2001 From: trippels Date: Sat, 29 Aug 2015 18:51:26 +0000 Subject: [PATCH] Fix c++/67371 (issues with throw in constexpr) As PR67371 shows gcc currently rejects all throw statements in constant-expressions, even when they are never executed. PR c++/67371 * constexpr.c (potential_constant_expression_1): Remove IF_STMT case. Move label to COND_EXPR case. Remove checking of SWITCH_STMT_BODY. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@227323 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/cp/ChangeLog | 7 ++++++ gcc/cp/constexpr.c | 14 +++--------- gcc/testsuite/g++.dg/cpp1y/constexpr-new.C | 11 +++++++++ gcc/testsuite/g++.dg/cpp1y/constexpr-throw.C | 34 ++++++++++++++++++++++++++++ 4 files changed, 55 insertions(+), 11 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp1y/constexpr-new.C create mode 100644 gcc/testsuite/g++.dg/cpp1y/constexpr-throw.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index b5a3398..7cbfa65 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2015-08-29 Markus Trippelsdorf + + PR c++/67371 + * constexpr.c (potential_constant_expression_1): Remove IF_STMT + case. Move label to COND_EXPR case. Remove checking of + SWITCH_STMT_BODY. + 2015-08-22 Paolo Carlini PR c++/63693 diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index 1eacb8b..0ff9b088 100644 --- a/gcc/cp/constexpr.c +++ b/gcc/cp/constexpr.c @@ -4273,15 +4273,6 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, return false; return true; - case IF_STMT: - if (!RECUR (IF_COND (t), rval)) - return false; - if (!RECUR (THEN_CLAUSE (t), any)) - return false; - if (!RECUR (ELSE_CLAUSE (t), any)) - return false; - return true; - case DO_STMT: if (!RECUR (DO_COND (t), rval)) return false; @@ -4310,8 +4301,8 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, case SWITCH_STMT: if (!RECUR (SWITCH_STMT_COND (t), rval)) return false; - if (!RECUR (SWITCH_STMT_BODY (t), any)) - return false; + /* FIXME we don't check SWITCH_STMT_BODY currently, because even + unreachable labels would be checked. */ return true; case STMT_EXPR: @@ -4592,6 +4583,7 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, return false; return true; + case IF_STMT: case COND_EXPR: case VEC_COND_EXPR: /* If the condition is a known constant, we know which of the legs we diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-new.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-new.C new file mode 100644 index 0000000..7241fef --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-new.C @@ -0,0 +1,11 @@ +// { dg-do compile { target c++14 } } + +constexpr int *f4(bool b) { + if (b) { + return nullptr; + } else { + return new int{42}; // { dg-error "call to non-constexpr" } + } +} +static_assert(f4(true) == nullptr, ""); +static_assert(f4(false) == nullptr, ""); // { dg-error "non-constant condition" } 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 0000000..ac90051 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-throw.C @@ -0,0 +1,34 @@ +// { dg-do compile { target c++14 } } + +constexpr void f1() { + if (false) + throw; +} + +constexpr void f2() { + if (true) + throw; +} // { dg-error "not a constant-expression" } + +constexpr void f3() { + if (false) + ; + else + throw; +}// { dg-error "not a constant-expression" } + +constexpr void f4() { + throw; +}// { dg-error "not a constant-expression" } + +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" } -- 2.7.4