diff mbox

C++ PATCH for c++/63925 (constexpr pointer increment)

Message ID 546B9961.6080602@redhat.com
State New
Headers show

Commit Message

Jason Merrill Nov. 18, 2014, 7:09 p.m. UTC
The middle-end doesn't like when I give it a PLUS_EXPR with pointer type.

Tested x86_64-pc-linux-gnu, applying to trunk.
diff mbox

Patch

commit 98e8254b2e89e1e34521a7cf9f027bd78eddd3ab
Author: Jason Merrill <jason@redhat.com>
Date:   Tue Nov 18 13:36:46 2014 -0500

    	PR c++/63925
    	* constexpr.c (cxx_eval_increment_expression): Use POINTER_PLUS_EXPR.

diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index 4325caa..5abea14 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -2566,8 +2566,17 @@  cxx_eval_increment_expression (const constexpr_ctx *ctx, tree t,
 
   /* The modified value.  */
   bool inc = (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR);
-  tree mod = fold_build2 (inc ? PLUS_EXPR : MINUS_EXPR,
-			  type, val, offset);
+  tree mod;
+  if (POINTER_TYPE_P (type))
+    {
+      /* The middle end requires pointers to use POINTER_PLUS_EXPR.  */
+      offset = convert_to_ptrofftype (offset);
+      if (!inc)
+	offset = fold_build1 (NEGATE_EXPR, TREE_TYPE (offset), offset);
+      mod = fold_build2 (POINTER_PLUS_EXPR, type, val, offset);
+    }
+  else
+    mod = fold_build2 (inc ? PLUS_EXPR : MINUS_EXPR, type, val, offset);
   VERIFY_CONSTANT (mod);
 
   /* Storing the modified value.  */
diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-incr1.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-incr1.C
index 2b099c8..ecd7c04 100644
--- a/gcc/testsuite/g++.dg/cpp1y/constexpr-incr1.C
+++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-incr1.C
@@ -1,4 +1,5 @@ 
 // { dg-do compile { target c++14 } }
+#define SA(X) static_assert((X),#X)
 
 constexpr int f (int i)
 {
@@ -8,6 +9,15 @@  constexpr int f (int i)
   return x;
 }
 
+constexpr int* g (int* p)
+{
+  ++p;
+  return p;
+}
+
 constexpr int i = f(42);
-#define SA(X) static_assert((X),#X)
 SA(i==44);
+
+int array[4];
+constexpr int* p = g(array);
+SA(p == &array[1]);