OSDN Git Service

PR c++/51489
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 19 Dec 2011 05:57:52 +0000 (05:57 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 19 Dec 2011 05:57:52 +0000 (05:57 +0000)
* semantics.c (cxx_eval_outermost_constant_expr): Check for
conversion from pointer to integer here.
(cxx_eval_constant_expression) [NOP_EXPR]: Not here.

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

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

index 7d625ee..6f1bc26 100644 (file)
@@ -1,3 +1,10 @@
+2011-12-19  Jason Merrill  <jason@redhat.com>
+
+       PR c++/51489
+       * semantics.c (cxx_eval_outermost_constant_expr): Check for
+       conversion from pointer to integer here.
+       (cxx_eval_constant_expression) [NOP_EXPR]: Not here.
+
 2011-12-18  Paolo Carlini  <paolo.carlini@oracle.com>
 
        * semantics.c (finish_compound_literal): Don't call check_narrowing
 2011-12-18  Paolo Carlini  <paolo.carlini@oracle.com>
 
        * semantics.c (finish_compound_literal): Don't call check_narrowing
index 76b0b18..e73b40a 100644 (file)
@@ -7704,17 +7704,6 @@ cxx_eval_constant_expression (const constexpr_call *call, tree t,
        tree oldop = TREE_OPERAND (t, 0);
        tree op = oldop;
        tree to = TREE_TYPE (t);
        tree oldop = TREE_OPERAND (t, 0);
        tree op = oldop;
        tree to = TREE_TYPE (t);
-       tree source = TREE_TYPE (op);
-        if (TYPE_PTR_P (source) && ARITHMETIC_TYPE_P (to)
-           && !(TREE_CODE (op) == COMPONENT_REF
-                && TYPE_PTRMEMFUNC_P (TREE_TYPE (TREE_OPERAND (op, 0)))))
-          {
-            if (!allow_non_constant)
-              error ("conversion of expression %qE of pointer type "
-                     "cannot yield a constant expression", op);
-           *non_constant_p = true;
-           return t;
-          }
        op = cxx_eval_constant_expression (call, TREE_OPERAND (t, 0),
                                           allow_non_constant, addr,
                                           non_constant_p);
        op = cxx_eval_constant_expression (call, TREE_OPERAND (t, 0),
                                           allow_non_constant, addr,
                                           non_constant_p);
@@ -7803,6 +7792,20 @@ cxx_eval_outermost_constant_expr (tree t, bool allow_non_constant)
       non_constant_p = true;
     }
 
       non_constant_p = true;
     }
 
+  /* Technically we should check this for all subexpressions, but that
+     runs into problems with our internal representation of pointer
+     subtraction and the 5.19 rules are still in flux.  */
+  if (CONVERT_EXPR_CODE_P (TREE_CODE (r))
+      && ARITHMETIC_TYPE_P (TREE_TYPE (r))
+      && TREE_CODE (TREE_OPERAND (r, 0)) == ADDR_EXPR)
+    {
+      if (!allow_non_constant)
+       error ("conversion from pointer type %qT "
+              "to arithmetic type %qT in a constant-expression",
+              TREE_TYPE (TREE_OPERAND (r, 0)), TREE_TYPE (r));
+      non_constant_p = true;
+    }
+
   if (non_constant_p && !allow_non_constant)
     return error_mark_node;
   else if (non_constant_p && TREE_CONSTANT (t))
   if (non_constant_p && !allow_non_constant)
     return error_mark_node;
   else if (non_constant_p && TREE_CONSTANT (t))
@@ -8110,25 +8113,10 @@ potential_constant_expression_1 (tree t, bool want_rval, tsubst_flags_t flags)
     case NOP_EXPR:
     case CONVERT_EXPR:
     case VIEW_CONVERT_EXPR:
     case NOP_EXPR:
     case CONVERT_EXPR:
     case VIEW_CONVERT_EXPR:
-      /* -- an array-to-pointer conversion that is applied to an lvalue
-            that designates an object with thread or automatic storage
-            duration;  FIXME not implemented as it breaks constexpr arrays;
-           need to fix the standard
-         -- a type conversion from a pointer or pointer-to-member type
-            to a literal type.  */
+      /* -- a reinterpret_cast.  FIXME not implemented, and this rule
+        may change to something more specific to type-punning (DR 1312).  */
       {
         tree from = TREE_OPERAND (t, 0);
       {
         tree from = TREE_OPERAND (t, 0);
-        tree source = TREE_TYPE (from);
-        tree target = TREE_TYPE (t);
-        if (TYPE_PTR_P (source) && ARITHMETIC_TYPE_P (target)
-           && !(TREE_CODE (from) == COMPONENT_REF
-                && TYPE_PTRMEMFUNC_P (TREE_TYPE (TREE_OPERAND (from, 0)))))
-          {
-            if (flags & tf_error)
-              error ("conversion of expression %qE of pointer type "
-                     "cannot yield a constant expression", from);
-            return false;
-          }
         return (potential_constant_expression_1
                (from, TREE_CODE (t) != VIEW_CONVERT_EXPR, flags));
       }
         return (potential_constant_expression_1
                (from, TREE_CODE (t) != VIEW_CONVERT_EXPR, flags));
       }
index 9562a9d..dc77cbe 100644 (file)
@@ -1,3 +1,8 @@
+2011-12-19  Jason Merrill  <jason@redhat.com>
+
+       PR c++/51489
+       * g++.dg/cpp0x/constexpr-ptrsub.C: New.
+
 2011-12-18  Hans-Peter Nilsson  <hp@axis.com>
 
        * gcc.dg/pr51491-2.c: Fix "cleanup-treee-dump" typo.
 2011-12-18  Hans-Peter Nilsson  <hp@axis.com>
 
        * gcc.dg/pr51491-2.c: Fix "cleanup-treee-dump" typo.
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-ptrsub.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-ptrsub.C
new file mode 100644 (file)
index 0000000..bccec73
--- /dev/null
@@ -0,0 +1,14 @@
+// PR c++/51489
+// DR 1313
+// { dg-options "-std=c++0x" }
+
+struct array
+{
+  constexpr array() :x(0) {}
+  constexpr int const* begin() { return &x; }
+  int x;
+};
+constexpr array aa;
+constexpr auto b = aa.begin();
+static_assert(b-b == 0, "compiles just fine");
+static_assert(aa.begin()-aa.begin() == 0, "compiler thinks it's not a constant expression");