Message ID | 20150829101410.GA421@x4 |
---|---|
State | New |
Headers | show |
On 2015.08.29 at 12:14 +0200, Markus Trippelsdorf wrote: > index 1eacb8be9a44..29a7f1f22169 100644 > --- a/gcc/cp/constexpr.c > +++ b/gcc/cp/constexpr.c > @@ -4276,10 +4276,10 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, > 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; > + if (integer_nonzerop (IF_COND (t)) && !RECUR (THEN_CLAUSE (t), any)) > + return false; > + if (integer_zerop (IF_COND (t)) && !RECUR (ELSE_CLAUSE (t), any)) > + return false; Sorry for messing up the formating of the return statements. I've fixed this locally already.
On 08/29/2015 06:14 AM, Markus Trippelsdorf wrote: > + if (integer_nonzerop (IF_COND (t)) && !RECUR (THEN_CLAUSE (t), any)) > + return false; > + if (integer_zerop (IF_COND (t)) && !RECUR (ELSE_CLAUSE (t), any)) > + return false; Actually, I think we can remove the IF_STMT code entirely and move the case label to the COND_EXPR case. Also, please add a comment explaining why we aren't checking SWITCH_STMT_BODY. Jason
diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index 1eacb8be9a44..29a7f1f22169 100644 --- a/gcc/cp/constexpr.c +++ b/gcc/cp/constexpr.c @@ -4276,10 +4276,10 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, 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; + if (integer_nonzerop (IF_COND (t)) && !RECUR (THEN_CLAUSE (t), any)) + return false; + if (integer_zerop (IF_COND (t)) && !RECUR (ELSE_CLAUSE (t), any)) + return false; return true; case DO_STMT: @@ -4310,8 +4310,6 @@ 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; return true; case STMT_EXPR: 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 000000000000..7241fefc41e5 --- /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 000000000000..ac90051d5e99 --- /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" }