aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2015-01-13 16:04:43 -0500
committerJason Merrill <jason@gcc.gnu.org>2015-01-13 16:04:43 -0500
commitcaee690e915e13a48a16dabbb61110ae88d1821a (patch)
tree9eaa74bed3b9d5c63d6e7a29849c7e6a834a3344 /gcc
parent7c368fb23cc92a3406e181ae361ebce3f5b9ab22 (diff)
downloadgcc-caee690e915e13a48a16dabbb61110ae88d1821a.zip
gcc-caee690e915e13a48a16dabbb61110ae88d1821a.tar.gz
gcc-caee690e915e13a48a16dabbb61110ae88d1821a.tar.bz2
re PR c++/64356 (Some constexpr expressions not recognized as constexpr)
PR c++/64356 PR libstdc++/58777 * constexpr.c (cxx_eval_binary_expression): Don't VERIFY_CONSTANT pointer expressions. (cxx_eval_increment_expression): Likewise. From-SVN: r219559
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/constexpr.c21
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/constexpr-local2.C22
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/pr63996.C2
4 files changed, 45 insertions, 6 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 668b13b..013c432 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,11 @@
2015-01-13 Jason Merrill <jason@redhat.com>
+ PR c++/64356
+ PR libstdc++/58777
+ * constexpr.c (cxx_eval_binary_expression): Don't VERIFY_CONSTANT
+ pointer expressions.
+ (cxx_eval_increment_expression): Likewise.
+
PR c++/64514
* pt.c (coerce_template_parameter_pack): Return NULL for a
zero-length fixed parameter pack with a pack expansion arg.
diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index 650250b..1432506 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -1616,10 +1616,15 @@ 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);
- VERIFY_CONSTANT (lhs);
+ /* 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);
rhs = cxx_eval_constant_expression (ctx, orig_rhs, /*lval*/false,
non_constant_p, overflow_p);
- VERIFY_CONSTANT (rhs);
+ if (!ptr)
+ VERIFY_CONSTANT (lhs);
location_t loc = EXPR_LOCATION (t);
enum tree_code code = TREE_CODE (t);
@@ -1634,7 +1639,8 @@ 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;
- VERIFY_CONSTANT (r);
+ if (!ptr)
+ VERIFY_CONSTANT (lhs);
return r;
}
@@ -2704,7 +2710,11 @@ cxx_eval_increment_expression (const constexpr_ctx *ctx, tree t,
tree val = rvalue (op);
val = cxx_eval_constant_expression (ctx, val, false,
non_constant_p, overflow_p);
- VERIFY_CONSTANT (val);
+ /* 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 (val));
+ if (!ptr)
+ VERIFY_CONSTANT (val);
/* The modified value. */
bool inc = (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR);
@@ -2719,7 +2729,8 @@ cxx_eval_increment_expression (const constexpr_ctx *ctx, tree t,
}
else
mod = fold_build2 (inc ? PLUS_EXPR : MINUS_EXPR, type, val, offset);
- VERIFY_CONSTANT (mod);
+ if (!ptr)
+ VERIFY_CONSTANT (mod);
/* Storing the modified value. */
tree store = build2 (MODIFY_EXPR, type, op, mod);
diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-local2.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-local2.C
new file mode 100644
index 0000000..fd6143b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-local2.C
@@ -0,0 +1,22 @@
+// PR c++/64356
+// { dg-do compile { target c++14 } }
+
+typedef unsigned long size_t;
+
+template<size_t N>
+constexpr size_t f(const char (&x)[N]) {
+ size_t s = 0;
+ for(size_t c : x)
+ s += c;
+ return s;
+}
+
+template<size_t N>
+constexpr size_t g(const char (&x)[N]) {
+ char y[N] = {0};
+ for(size_t i = 0; i < N; ++i)
+ y[i] = x[i];
+ return f(y);
+}
+
+constexpr auto x = g(__DATE__);
diff --git a/gcc/testsuite/g++.dg/cpp1y/pr63996.C b/gcc/testsuite/g++.dg/cpp1y/pr63996.C
index d0bf9b5..8f66cdc 100644
--- a/gcc/testsuite/g++.dg/cpp1y/pr63996.C
+++ b/gcc/testsuite/g++.dg/cpp1y/pr63996.C
@@ -6,5 +6,5 @@ foo (int i)
int a[i] = { }; // { dg-error "forbids variable length" }
}
-constexpr int j = foo (1); // { dg-error "is not a constant expression" }
+constexpr int j = foo (1); // { dg-error "flows off the end" }