summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortrippels <trippels@138bc75d-0d04-0410-961f-82ee72b054a4>2015-08-29 18:51:26 +0000
committertrippels <trippels@138bc75d-0d04-0410-961f-82ee72b054a4>2015-08-29 18:51:26 +0000
commit748c426a1b106499ced440f548743efdde564d4d (patch)
tree813dae7e59ddb927d2ea8535efd5aa49086dc622
parent08bd9c7ad6acfcef822747dfbb6b56e3b92f34a1 (diff)
downloadgcc-748c426a1b106499ced440f548743efdde564d4d.tar.gz
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
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/constexpr.c14
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/constexpr-new.C11
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/constexpr-throw.C34
4 files changed, 55 insertions, 11 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index b5a3398c8dc..7cbfa6591f1 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,10 @@
+2015-08-29 Markus Trippelsdorf <markus@trippelsdorf.de>
+
+ 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 <paolo.carlini@oracle.com>
PR c++/63693
diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index 1eacb8be9a4..0ff9b088cc2 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 00000000000..7241fefc41e
--- /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 00000000000..ac90051d5e9
--- /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" }