re PR c++/51489 (constexpr not working consistently)
authorJason Merrill <jason@redhat.com>
Wed, 2 Mar 2016 02:32:44 +0000 (21:32 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Wed, 2 Mar 2016 02:32:44 +0000 (21:32 -0500)
PR c++/51489

* constexpr.c (cxx_eval_binary_expression): Don't VERIFY_CONSTANT
the operands.

From-SVN: r233878

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

index 3a24cc9392b8665b4e1e360bbdbe88bd58d6eb16..e8be35d1a73671840ddd214656db723fe0db65ca 100644 (file)
@@ -1,5 +1,9 @@
 2016-03-01  Jason Merrill  <jason@redhat.com>
 
+       PR c++/51489
+       * constexpr.c (cxx_eval_binary_expression): Don't VERIFY_CONSTANT
+       the operands.
+
        PR c++/69995
        * constexpr.c (cxx_eval_call_expression): Unshare arg.
        (cxx_eval_constant_expression) [DECL_EXPR]: Unshare init.
index a21997ab97a3305b865e0499690dfca849ef784a..bcb129f22c4a2154f2307c5b3d535c7dcb1a25b2 100644 (file)
@@ -1612,15 +1612,14 @@ cxx_eval_binary_expression (const constexpr_ctx *ctx, tree t,
   tree lhs, rhs;
   lhs = cxx_eval_constant_expression (ctx, orig_lhs, /*lval*/false,
                                      non_constant_p, overflow_p);
-  /* Don't VERIFY_CONSTANT if this might be dealing with a pointer to
-     a local array in a constexpr function.  */
-  bool ptr = POINTER_TYPE_P (TREE_TYPE (lhs));
-  if (!ptr)
-    VERIFY_CONSTANT (lhs);
+  /* Don't VERIFY_CONSTANT here, it's unnecessary and will break pointer
+     subtraction.  */
+  if (*non_constant_p)
+    return t;
   rhs = cxx_eval_constant_expression (ctx, orig_rhs, /*lval*/false,
                                      non_constant_p, overflow_p);
-  if (!ptr)
-    VERIFY_CONSTANT (rhs);
+  if (*non_constant_p)
+    return t;
 
   location_t loc = EXPR_LOCATION (t);
   enum tree_code code = TREE_CODE (t);
@@ -1653,6 +1652,9 @@ cxx_eval_binary_expression (const constexpr_ctx *ctx, tree t,
     }
   else if (cxx_eval_check_shift_p (loc, ctx, code, type, lhs, rhs))
     *non_constant_p = true;
+  /* Don't VERIFY_CONSTANT if this might be dealing with a pointer to
+     a local array in a constexpr function.  */
+  bool ptr = POINTER_TYPE_P (TREE_TYPE (lhs));
   if (!ptr)
     VERIFY_CONSTANT (r);
   return r;
diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-array4.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-array4.C
new file mode 100644 (file)
index 0000000..fc01047
--- /dev/null
@@ -0,0 +1,12 @@
+// { dg-do compile { target c++14 } }
+
+constexpr bool g()
+{
+  int ar[4] = { 1, 2, 3, 4 };
+  auto e1 = ar;
+  auto e4 = ar+3;
+  return (e4-e1) == 3;
+}
+
+#define SA(X) static_assert((X),#X)
+SA(g());