Hi! As the testcase shows, we also want to fold "abcd" + 3 != NULL at constant time. The following patch fixes that. Additionally, I think if !indirect_base0 then we basically want to compare whether the base0's value rather than address is non-NULL, which we can't optimize. All we can optimize is when indirect_base0 is true, i.e. we want to ask whether base0's address + some constant offset is non-NULL.
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2016-12-05 Jakub Jelinek <ja...@redhat.com> PR c++/71537 * fold-const.c (fold_comparison): Assume CONSTANT_CLASS_P (base0) plus offset is non-zero. For maybe_nonzero_address decl base0, require indirect_base0. * g++.dg/cpp0x/constexpr-71537.C: New test. --- gcc/fold-const.c.jj 2016-11-23 16:47:32.000000000 +0100 +++ gcc/fold-const.c 2016-12-05 15:17:29.425739667 +0100 @@ -8419,14 +8419,16 @@ fold_comparison (location_t loc, enum tr below follow the C++ rules with the additional property that every object pointer compares greater than a null pointer. */ - else if (DECL_P (base0) - && maybe_nonzero_address (base0) > 0 - /* Avoid folding references to struct members at offset 0 to - prevent tests like '&ptr->firstmember == 0' from getting - eliminated. When ptr is null, although the -> expression - is strictly speaking invalid, GCC retains it as a matter - of QoI. See PR c/44555. */ - && (offset0 == NULL_TREE && bitpos0 != 0) + else if (((DECL_P (base0) + && maybe_nonzero_address (base0) > 0 + /* Avoid folding references to struct members at offset 0 to + prevent tests like '&ptr->firstmember == 0' from getting + eliminated. When ptr is null, although the -> expression + is strictly speaking invalid, GCC retains it as a matter + of QoI. See PR c/44555. */ + && (offset0 == NULL_TREE && bitpos0 != 0)) + || CONSTANT_CLASS_P (base0)) + && indirect_base0 /* The caller guarantees that when one of the arguments is constant (i.e., null in this case) it is second. */ && integer_zerop (arg1)) --- gcc/testsuite/g++.dg/cpp0x/constexpr-71537.C.jj 2016-12-05 15:34:09.648000207 +0100 +++ gcc/testsuite/g++.dg/cpp0x/constexpr-71537.C 2016-12-05 15:33:47.000000000 +0100 @@ -0,0 +1,18 @@ +// PR c++/71537 +// { dg-do compile { target c++11 } } + +constexpr int n[42] = {1}; +constexpr int x1 = n ? 1 : 0; +constexpr int x2 = n + 1 ? 1 : 0; +constexpr int x3 = "abc" ? 1 : 0; +constexpr int x4 = "abc" + 1 ? 1 : 0; +constexpr bool x5 = "abc" + 1; +constexpr bool x6 = "abc" + 4; +constexpr bool x7 = n + 42; +static_assert (x1 == 1, ""); +static_assert (x2 == 1, ""); +static_assert (x3 == 1, ""); +static_assert (x4 == 1, ""); +static_assert (x5, ""); +static_assert (x6, ""); +static_assert (x7, ""); Jakub