This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH for c++/46369 (C++0x ICE with bitfield)
- From: Jason Merrill <jason at redhat dot com>
- To: gcc-patches List <gcc-patches at gcc dot gnu dot org>
- Date: Wed, 10 Nov 2010 18:07:16 -0600
- Subject: C++ PATCH for c++/46369 (C++0x ICE with bitfield)
Since fold_binary can turn a COMPONENT_REF into a BIT_FIELD_REF, I need
to deal with it.
Tested x86_64-pc-linux-gnu, applied to trunk.
commit 1bf00ede219cbc994aa4be4819ff14b8ebc5fa82
Author: Jason Merrill <jason@redhat.com>
Date: Wed Nov 10 17:09:39 2010 -0600
PR c++/46369
* semantics.c (cxx_eval_bit_field_ref): New.
(cxx_eval_constant_expression): Call it.
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index b48559e..38e03f6 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -6264,6 +6264,45 @@ cxx_eval_component_reference (const constexpr_call *call, tree t,
}
/* Subroutine of cxx_eval_constant_expression.
+ Attempt to reduce a field access of a value of class type that is
+ expressed as a BIT_FIELD_REF. */
+
+static tree
+cxx_eval_bit_field_ref (const constexpr_call *call, tree t,
+ bool allow_non_constant, bool addr,
+ bool *non_constant_p)
+{
+ tree orig_whole = TREE_OPERAND (t, 0);
+ tree whole = cxx_eval_constant_expression (call, orig_whole,
+ allow_non_constant, addr,
+ non_constant_p);
+ tree start, field, value;
+ unsigned HOST_WIDE_INT i;
+
+ if (whole == orig_whole)
+ return t;
+ /* Don't VERIFY_CONSTANT here; we only want to check that we got a
+ CONSTRUCTOR. */
+ if (!*non_constant_p && TREE_CODE (whole) != CONSTRUCTOR)
+ {
+ if (!allow_non_constant)
+ error ("%qE is not a constant expression", orig_whole);
+ *non_constant_p = true;
+ }
+ if (*non_constant_p)
+ return t;
+
+ start = TREE_OPERAND (t, 2);
+ FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (whole), i, field, value)
+ {
+ if (bit_position (field) == start)
+ return value;
+ }
+ gcc_unreachable();
+ return error_mark_node;
+}
+
+/* Subroutine of cxx_eval_constant_expression.
Evaluate a short-circuited logical expression T in the context
of a given constexpr CALL. BAILOUT_VALUE is the value for
early return. CONTINUE_VALUE is used here purely for
@@ -6841,6 +6880,11 @@ cxx_eval_constant_expression (const constexpr_call *call, tree t,
non_constant_p);
break;
+ case BIT_FIELD_REF:
+ r = cxx_eval_bit_field_ref (call, t, allow_non_constant, addr,
+ non_constant_p);
+ break;
+
case COND_EXPR:
case VEC_COND_EXPR:
r = cxx_eval_conditional_expression (call, t, allow_non_constant, addr,
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-bitfield.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-bitfield.C
new file mode 100644
index 0000000..7eba498
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-bitfield.C
@@ -0,0 +1,10 @@
+// PR c++/46369
+// { dg-options -std=c++0x }
+
+struct A
+{
+ unsigned i : 1;
+};
+
+constexpr A f() { return { 1 }; }
+constexpr bool b = (f().i == 1);