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;