diff options
author | Jason Merrill <jason@redhat.com> | 2010-11-10 19:06:34 -0500 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2010-11-10 19:06:34 -0500 |
commit | 4ddf1c7f493b6288cba885348e69d61bc1da8a53 (patch) | |
tree | c785ed676f302e79f948b4e4b322582bad60e785 /gcc/cp | |
parent | a34779030e763fc62e90f78cfc6d368a8c120fed (diff) | |
download | gcc-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/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/semantics.c | 44 |
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, |