From 894bec688558a3f8d9a5398df66adb4d45f6fa26 Mon Sep 17 00:00:00 2001 From: Marek Polacek Date: Thu, 2 Apr 2015 16:51:27 +0000 Subject: [PATCH] re PR c++/65642 ([C++11] GCC rejects valid constant expression) PR c++/65642 * constexpr.c (cxx_eval_pointer_plus_expression): Call cxx_eval_constant_expression on the first operand. * g++.dg/cpp0x/constexpr-fold1.C: New test. * g++.dg/cpp0x/constexpr-fold2.C: New test. From-SVN: r221843 --- gcc/cp/ChangeLog | 6 ++ gcc/cp/constexpr.c | 3 + gcc/testsuite/ChangeLog | 6 ++ gcc/testsuite/g++.dg/cpp0x/constexpr-fold1.C | 65 ++++++++++++++++++++ gcc/testsuite/g++.dg/cpp0x/constexpr-fold2.C | 30 +++++++++ 5 files changed, 110 insertions(+) create mode 100644 gcc/testsuite/g++.dg/cpp0x/constexpr-fold1.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/constexpr-fold2.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 6f300fb20da..ca048aaaefb 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2015-04-02 Marek Polacek + + PR c++/65642 + * constexpr.c (cxx_eval_pointer_plus_expression): Call + cxx_eval_constant_expression on the first operand. + 2015-04-01 Jason Merrill PR c++/65625 diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index 2100f94cdd0..f5be8dfb46c 100644 --- a/gcc/cp/constexpr.c +++ b/gcc/cp/constexpr.c @@ -2933,6 +2933,9 @@ cxx_eval_pointer_plus_expression (const constexpr_ctx *ctx, tree t, tree op01 = TREE_OPERAND (t, 1); location_t loc = EXPR_LOCATION (t); + op00 = cxx_eval_constant_expression (ctx, op00, lval, + non_constant_p, overflow_p); + STRIP_NOPS (op00); if (TREE_CODE (op00) != ADDR_EXPR) return NULL_TREE; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a22eb607808..9b99c189257 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2015-04-02 Marek Polacek + + PR c++/65642 + * g++.dg/cpp0x/constexpr-fold1.C: New test. + * g++.dg/cpp0x/constexpr-fold2.C: New test. + 2015-04-02 Jakub Jelinek PR preprocessor/61977 diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-fold1.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-fold1.C new file mode 100644 index 00000000000..414a0dacf99 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-fold1.C @@ -0,0 +1,65 @@ +// PR c++/65642 +// { dg-do compile { target c++11 } } + +// Check we're able to evaluate these. + +#define SA(X) static_assert((X),#X) + +constexpr char s[] = "abc"; +constexpr int t[] = { 'a', 'b', 'c', '\0' }; + +constexpr char +fn1 (const char *p) +{ + return *(p + 1); +} + +constexpr char +fn2 (const char *p) +{ + return p[1]; +} + +constexpr int +fn3 (const int *p) +{ + return *(p + 1); +} + +constexpr int +fn4 (const int *p) +{ + return p[1]; +} + +constexpr auto c1 = fn1 (&s[0]); +constexpr auto c2 = fn1 (&s[1]); +constexpr auto c3 = fn1 (&s[2]); + +SA (c1 == 'b'); +SA (c2 == 'c'); +SA (c3 == '\0'); + +constexpr auto d1 = fn2 (&s[0]); +constexpr auto d2 = fn2 (&s[1]); +constexpr auto d3 = fn2 (&s[2]); + +SA (d1 == 'b'); +SA (d2 == 'c'); +SA (d3 == '\0'); + +constexpr auto e1 = fn3 (&t[0]); +constexpr auto e2 = fn3 (&t[1]); +constexpr auto e3 = fn3 (&t[2]); + +SA (e1 == 'b'); +SA (e2 == 'c'); +SA (e3 == '\0'); + +constexpr auto f1 = fn4 (&t[0]); +constexpr auto f2 = fn4 (&t[1]); +constexpr auto f3 = fn4 (&t[2]); + +SA (f1 == 'b'); +SA (f2 == 'c'); +SA (f3 == '\0'); diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-fold2.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-fold2.C new file mode 100644 index 00000000000..98aca2a2ce0 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-fold2.C @@ -0,0 +1,30 @@ +// PR c++/65642 +// { dg-do compile { target c++11 } } + +#define SA(X) static_assert((X),#X) + +constexpr char s[] = "abc"; + +constexpr bool +cmp (char const *a, char const *b) +{ + return a == b; +} + +constexpr bool +fn1 (const char *s) +{ + return cmp (s, s + 1); +} + +constexpr bool +fn2 (const char *s) +{ + return cmp (s + 1, s + 1); +} + +constexpr auto c1 = fn1 (&s[0]); +constexpr auto c2 = fn2 (&s[0]); + +SA (!c1); +SA (c2); -- 2.30.2