cxx_eval_logical_expression was assuming that a folded first operand of && would be either boolean_true_node or boolean_false_node, but in fact it can be a constant with a typedef of bool, which doesn't compare equal with ==. So we should use tree_int_cst_equal to compare them instead.

Tested x86_64-pc-linux-gnu, applying to trunk.
commit 75fff91977aadc3ba784553b881a8e5222308194
Author: Jason Merrill <ja...@redhat.com>
Date:   Mon Sep 26 17:28:27 2011 -0400

    	PR c++/50508
    	* semantics.c (cxx_eval_logical_expression): Use tree_int_cst_equal
    	rather than ==.

diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 19ecbee..89c76d5 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -6680,9 +6680,9 @@ cxx_eval_logical_expression (const constexpr_call *call, tree t,
 					   allow_non_constant, addr,
 					   non_constant_p);
   VERIFY_CONSTANT (lhs);
-  if (lhs == bailout_value)
+  if (tree_int_cst_equal (lhs, bailout_value))
     return lhs;
-  gcc_assert (lhs == continue_value);
+  gcc_assert (tree_int_cst_equal (lhs, continue_value));
   r = cxx_eval_constant_expression (call, TREE_OPERAND (t, 1),
 				    allow_non_constant, addr, non_constant_p);
   VERIFY_CONSTANT (r);
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-typedef1.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-typedef1.C
new file mode 100644
index 0000000..2719e3a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-typedef1.C
@@ -0,0 +1,11 @@
+// PR c++/50508
+// { dg-options -std=c++0x }
+
+template <class T>
+  struct integral_constant {
+    typedef T value_type;
+    constexpr operator value_type() { return true; }
+  };
+
+static constexpr bool value = integral_constant<bool>()
+                              && true;

Reply via email to