OSDN Git Service

PR c++/46369
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 11 Nov 2010 00:06:34 +0000 (00:06 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 11 Nov 2010 00:06:34 +0000 (00:06 +0000)
* semantics.c (cxx_eval_bit_field_ref): New.
(cxx_eval_constant_expression): Call it.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@166576 138bc75d-0d04-0410-961f-82ee72b054a4

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

index e5fa280..f85f4b1 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 b48559e..38e03f6 100644 (file)
@@ -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,
index c506e33..4c10cc7 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);