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
This commit is contained in:
Jason Merrill 2015-01-13 16:04:43 -05:00 committed by Jason Merrill
parent 7c368fb23c
commit caee690e91
7 changed files with 45 additions and 15 deletions

View File

@ -1,5 +1,11 @@
2015-01-13 Jason Merrill <jason@redhat.com> 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 PR c++/64514
* pt.c (coerce_template_parameter_pack): Return NULL for a * pt.c (coerce_template_parameter_pack): Return NULL for a
zero-length fixed parameter pack with a pack expansion arg. zero-length fixed parameter pack with a pack expansion arg.

View File

@ -1616,10 +1616,15 @@ cxx_eval_binary_expression (const constexpr_ctx *ctx, tree t,
tree lhs, rhs; tree lhs, rhs;
lhs = cxx_eval_constant_expression (ctx, orig_lhs, /*lval*/false, lhs = cxx_eval_constant_expression (ctx, orig_lhs, /*lval*/false,
non_constant_p, overflow_p); 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, rhs = cxx_eval_constant_expression (ctx, orig_rhs, /*lval*/false,
non_constant_p, overflow_p); non_constant_p, overflow_p);
VERIFY_CONSTANT (rhs); if (!ptr)
VERIFY_CONSTANT (lhs);
location_t loc = EXPR_LOCATION (t); location_t loc = EXPR_LOCATION (t);
enum tree_code code = TREE_CODE (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)) else if (cxx_eval_check_shift_p (loc, ctx, code, type, lhs, rhs))
*non_constant_p = true; *non_constant_p = true;
VERIFY_CONSTANT (r); if (!ptr)
VERIFY_CONSTANT (lhs);
return r; return r;
} }
@ -2704,7 +2710,11 @@ cxx_eval_increment_expression (const constexpr_ctx *ctx, tree t,
tree val = rvalue (op); tree val = rvalue (op);
val = cxx_eval_constant_expression (ctx, val, false, val = cxx_eval_constant_expression (ctx, val, false,
non_constant_p, overflow_p); 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. */ /* The modified value. */
bool inc = (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR); bool inc = (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR);
@ -2719,7 +2729,8 @@ cxx_eval_increment_expression (const constexpr_ctx *ctx, tree t,
} }
else else
mod = fold_build2 (inc ? PLUS_EXPR : MINUS_EXPR, type, val, offset); mod = fold_build2 (inc ? PLUS_EXPR : MINUS_EXPR, type, val, offset);
VERIFY_CONSTANT (mod); if (!ptr)
VERIFY_CONSTANT (mod);
/* Storing the modified value. */ /* Storing the modified value. */
tree store = build2 (MODIFY_EXPR, type, op, mod); tree store = build2 (MODIFY_EXPR, type, op, mod);

View File

@ -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__);

View File

@ -6,5 +6,5 @@ foo (int i)
int a[i] = { }; // { dg-error "forbids variable length" } 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" }

View File

@ -1,7 +1,4 @@
// { dg-options "-std=gnu++14" } // { dg-options "-std=gnu++14" }
// XFAIL pending resolution of PR libstdc++/58777
// { dg-do compile { xfail *-*-* } }
// { dg-excess-errors "" }
// Copyright (C) 2013-2015 Free Software Foundation, Inc. // Copyright (C) 2013-2015 Free Software Foundation, Inc.
// //

View File

@ -1,7 +1,4 @@
// { dg-options "-std=gnu++14" } // { dg-options "-std=gnu++14" }
// XFAIL pending resolution of PR libstdc++/58777
// { dg-do compile { xfail *-*-* } }
// { dg-excess-errors "" }
// Copyright (C) 2013-2015 Free Software Foundation, Inc. // Copyright (C) 2013-2015 Free Software Foundation, Inc.
// //

View File

@ -1,7 +1,4 @@
// { dg-options "-std=gnu++14" } // { dg-options "-std=gnu++14" }
// XFAIL pending resolution of PR libstdc++/58777
// { dg-do compile { xfail *-*-* } }
// { dg-excess-errors "" }
// Copyright (C) 2013-2015 Free Software Foundation, Inc. // Copyright (C) 2013-2015 Free Software Foundation, Inc.
// //