Patchwork C++ PATCH for c++/47570 (constexpr failure with >=)

login
register
mail settings
Submitter Jason Merrill
Date March 17, 2011, 2:25 a.m.
Message ID <4D817137.8000403@redhat.com>
Download mbox | patch
Permalink /patch/87328/
State New
Headers show

Comments

Jason Merrill - March 17, 2011, 2:25 a.m.
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 <jason@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.

Patch

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;
+}