re PR c++/46369 (ICE: unexpected expression '((unsigned char*)&*r)[24]' of kind bit_f...
authorJason Merrill <jason@redhat.com>
Thu, 11 Nov 2010 00:06:34 +0000 (19:06 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Thu, 11 Nov 2010 00:06:34 +0000 (19:06 -0500)
PR c++/46369
* semantics.c (cxx_eval_bit_field_ref): New.
(cxx_eval_constant_expression): Call it.

From-SVN: r166576

gcc/cp/ChangeLog
gcc/cp/semantics.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp0x/constexpr-bitfield.C [new file with mode: 0644]

index e5fa280dc777b3badf6d889dcde5bbf73c0d2213..f85f4b1619f18b26c1b439d1666b9c72d2f70206 100644 (file)
@@ -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.
index b48559e81aa0454f636b3c7306eb295920128d17..38e03f6060de89a604756d0f8f6bc46a93b4496f 100644 (file)
@@ -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,
index c506e33d4d1cb69fa30807be7775ba06311c6f5f..4c10cc7a6c76f638c1aae2bc1b0dd9e4e711e1da 100644 (file)
@@ -1,3 +1,7 @@
+2010-11-10  Jason Merrill  <jason@redhat.com>
+
+       * g++.dg/cpp0x/constexpr-bitfield.C: New.
+
 2010-11-10  Jakub Jelinek  <jakub@redhat.com>
 
        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 (file)
index 0000000..7eba498
--- /dev/null
@@ -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);