aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2010-11-10 19:06:34 -0500
committerJason Merrill <jason@gcc.gnu.org>2010-11-10 19:06:34 -0500
commit4ddf1c7f493b6288cba885348e69d61bc1da8a53 (patch)
treec785ed676f302e79f948b4e4b322582bad60e785 /gcc/cp
parenta34779030e763fc62e90f78cfc6d368a8c120fed (diff)
downloadgcc-4ddf1c7f493b6288cba885348e69d61bc1da8a53.zip
gcc-4ddf1c7f493b6288cba885348e69d61bc1da8a53.tar.gz
gcc-4ddf1c7f493b6288cba885348e69d61bc1da8a53.tar.bz2
re PR c++/46369 (ICE: unexpected expression '((unsigned char*)&*r)[24]' of kind bit_field_ref)
PR c++/46369 * semantics.c (cxx_eval_bit_field_ref): New. (cxx_eval_constant_expression): Call it. From-SVN: r166576
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/semantics.c44
2 files changed, 50 insertions, 0 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index e5fa280..f85f4b1 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,9 @@
+2010-11-10 Jason Merrill <jason@redhat.com>
+
+ PR c++/46369
+ * semantics.c (cxx_eval_bit_field_ref): New.
+ (cxx_eval_constant_expression): Call it.
+
2010-11-10 Joseph Myers <joseph@codesourcery.com>
* cvt.c (cp_convert_to_pointer): Use %' in diagnostic.
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,