From bf2d0849a360376182b796042fedaa018b87d605 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Tue, 6 Dec 2016 10:22:36 +0100 Subject: [PATCH] re PR c++/71537 (GCC rejects consetxpr boolean conversions and comparisons on the result of pointer arithmetic.) PR c++/71537 * fold-const-call.c (fold_const_call): Handle CFN_BUILT_IN_{INDEX,STRCHR,RINDEX,STRRCHR}. * g++.dg/cpp0x/constexpr-strchr.C: New test. From-SVN: r243284 --- gcc/ChangeLog | 4 +++ gcc/fold-const-call.c | 25 +++++++++++++++++ gcc/testsuite/ChangeLog | 3 +++ gcc/testsuite/g++.dg/cpp0x/constexpr-strchr.C | 27 +++++++++++++++++++ 4 files changed, 59 insertions(+) create mode 100644 gcc/testsuite/g++.dg/cpp0x/constexpr-strchr.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4e70e2705b0..029dbdca00b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,9 @@ 2016-12-06 Jakub Jelinek + PR c++/71537 + * fold-const-call.c (fold_const_call): Handle + CFN_BUILT_IN_{INDEX,STRCHR,RINDEX,STRRCHR}. + PR tree-optimization/78675 * tree-vect-loop.c (vectorizable_live_operation): For VECTOR_BOOLEAN_TYPE_P vectype use integral type with bitsize precision diff --git a/gcc/fold-const-call.c b/gcc/fold-const-call.c index e2d0eaf0228..439988d7170 100644 --- a/gcc/fold-const-call.c +++ b/gcc/fold-const-call.c @@ -1383,6 +1383,7 @@ tree fold_const_call (combined_fn fn, tree type, tree arg0, tree arg1) { const char *p0, *p1; + char c; switch (fn) { case CFN_BUILT_IN_STRSPN: @@ -1409,6 +1410,30 @@ fold_const_call (combined_fn fn, tree type, tree arg0, tree arg1) } return NULL_TREE; + case CFN_BUILT_IN_INDEX: + case CFN_BUILT_IN_STRCHR: + if ((p0 = c_getstr (arg0)) && target_char_cst_p (arg1, &c)) + { + const char *r = strchr (p0, c); + if (r == NULL) + return build_int_cst (type, 0); + return fold_convert (type, + fold_build_pointer_plus_hwi (arg0, r - p0)); + } + return NULL_TREE; + + case CFN_BUILT_IN_RINDEX: + case CFN_BUILT_IN_STRRCHR: + if ((p0 = c_getstr (arg0)) && target_char_cst_p (arg1, &c)) + { + const char *r = strrchr (p0, c); + if (r == NULL) + return build_int_cst (type, 0); + return fold_convert (type, + fold_build_pointer_plus_hwi (arg0, r - p0)); + } + return NULL_TREE; + default: return fold_const_call_1 (fn, type, arg0, arg1); } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 35f10fe0563..e6dfcdcf599 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2016-12-06 Jakub Jelinek + PR c++/71537 + * g++.dg/cpp0x/constexpr-strchr.C: New test. + PR tree-optimization/78675 * gcc.c-torture/execute/pr78675.c: New test. * gcc.target/i386/pr78675-1.c: New test. diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-strchr.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-strchr.C new file mode 100644 index 00000000000..c44d8a28b78 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-strchr.C @@ -0,0 +1,27 @@ +// { dg-do compile { target c++11 } } + +constexpr const char *f1 (const char *p, int q) { return __builtin_strchr (p, q); } +constexpr const char *f2 (const char *p, int q) { return __builtin_index (p, q); } +constexpr const char *f3 (const char *p, int q) { return __builtin_strrchr (p, q); } +constexpr const char *f4 (const char *p, int q) { return __builtin_rindex (p, q); } +constexpr const char a[] = "abcdefedcba"; +static_assert (f1 ("abcde", 'f') == nullptr, ""); +static_assert (f1 (a, 'g') == nullptr, ""); +static_assert (f1 (a, 'f') == a + 5, ""); +static_assert (f1 (a, 'c') == a + 2, ""); +static_assert (f1 (a, '\0') == a + 11, ""); +static_assert (f2 ("abcde", 'f') == nullptr, ""); +static_assert (f2 (a, 'g') == nullptr, ""); +static_assert (f2 (a, 'f') == a + 5, ""); +static_assert (f2 (a, 'c') == a + 2, ""); +static_assert (f2 (a, '\0') == a + 11, ""); +static_assert (f3 ("abcde", 'f') == nullptr, ""); +static_assert (f3 (a, 'g') == nullptr, ""); +static_assert (f3 (a, 'f') == a + 5, ""); +static_assert (f3 (a, 'c') == a + 8, ""); +static_assert (f3 (a, '\0') == a + 11, ""); +static_assert (f4 ("abcde", 'f') == nullptr, ""); +static_assert (f4 (a, 'g') == nullptr, ""); +static_assert (f4 (a, 'f') == a + 5, ""); +static_assert (f4 (a, 'c') == a + 8, ""); +static_assert (f4 (a, '\0') == a + 11, ""); -- 2.30.2