From 4ddf1c7f493b6288cba885348e69d61bc1da8a53 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Wed, 10 Nov 2010 19:06:34 -0500 Subject: [PATCH] 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 --- gcc/cp/ChangeLog | 6 +++ gcc/cp/semantics.c | 44 +++++++++++++++++++ gcc/testsuite/ChangeLog | 4 ++ .../g++.dg/cpp0x/constexpr-bitfield.C | 10 +++++ 4 files changed, 64 insertions(+) create mode 100644 gcc/testsuite/g++.dg/cpp0x/constexpr-bitfield.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index e5fa280dc77..f85f4b1619f 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2010-11-10 Jason Merrill + + PR c++/46369 + * semantics.c (cxx_eval_bit_field_ref): New. + (cxx_eval_constant_expression): Call it. + 2010-11-10 Joseph Myers * cvt.c (cp_convert_to_pointer): Use %' in diagnostic. diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index b48559e81aa..38e03f6060d 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -6263,6 +6263,45 @@ cxx_eval_component_reference (const constexpr_call *call, tree t, return error_mark_node; } +/* 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 @@ -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/ChangeLog b/gcc/testsuite/ChangeLog index c506e33d4d1..4c10cc7a6c7 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2010-11-10 Jason Merrill + + * g++.dg/cpp0x/constexpr-bitfield.C: New. + 2010-11-10 Jakub Jelinek PR debug/46409 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 00000000000..7eba49833f2 --- /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); -- 2.30.2