In this case, fold is turning one() >= 0 into (one(), true) because the
comparison is always true because one() returns unsigned, and we were
handling COMPOUND_EXPR like any other binary expression, expecting fold
to turn (1, 1) into 1. But it doesn't, and it makes sense to handle
COMPOUND_EXPR differently.
Tested x86_64-pc-linux-gnu, applying to trunk.
commit ff191a21f0a3dbff8ab4d2788e3fa5b072657c6e
Author: Jason Merrill <ja...@redhat.com>
Date: Wed Mar 16 16:50:10 2011 -0400
PR c++/47570
* semantics.c (cxx_eval_constant_expression) [COMPOUND_EXPR]: Don't
use the generic binary expression handling.
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index ce24d46..a0c5ae3 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -6915,7 +6915,13 @@ cxx_eval_constant_expression (const constexpr_call
*call, tree t,
r = cxx_eval_constant_expression (call, op0, allow_non_constant,
addr, non_constant_p);
else
- goto binary;
+ {
+ /* Check that the LHS is constant and then discard it. */
+ cxx_eval_constant_expression (call, op0, allow_non_constant,
+ false, non_constant_p);
+ r = cxx_eval_constant_expression (call, op1, allow_non_constant,
+ addr, non_constant_p);
+ }
}
break;
@@ -6957,7 +6963,6 @@ cxx_eval_constant_expression (const constexpr_call *call,
tree t,
case UNEQ_EXPR:
case RANGE_EXPR:
case COMPLEX_EXPR:
- binary:
r = cxx_eval_binary_expression (call, t, allow_non_constant, addr,
non_constant_p);
break;
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-47570.C
b/gcc/testsuite/g++.dg/cpp0x/constexpr-47570.C
new file mode 100644
index 0000000..c60ba86
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-47570.C
@@ -0,0 +1,25 @@
+// PR c++/47570
+// { dg-options -std=c++0x }
+
+unsigned int constexpr one()
+{ return 1; }
+
+int constexpr one_B()
+{ return 1; }
+
+int main()
+{
+ // FAIL TO COMPILE:
+ static bool constexpr SC_huh1 = ((unsigned int)one()) >= ((unsigned int)0);
+ static bool constexpr SC_huh2 = one() >= ((unsigned int)0);
+ static bool constexpr SC_huh3 = one() >= 0;
+
+ // COMPILE OK:
+ static bool constexpr SC_huh4 = ((one() == 0) || (one() > 0));
+ static bool constexpr SC_huh5 = one() == 0;
+ static bool constexpr SC_huh6 = one() > 0;
+ static bool constexpr SC_huh7 = one_B() >= 0;
+ static bool constexpr SC_huh8 = one() >= 1;
+
+ return SC_huh3;
+}