Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for trunk?
-- >8 -- Here the flag -fno-delete-null-pointer-checks causes the trivial address comparison in inline int a, b; static_assert(&a != &b); to be rejected as non-constant because with the flag we can't assume such weak symbols are non-NULL, which causes symtab/fold-const.cc to punt on such comparisons. Note this also affects -fsanitize=undefined since it implies -fno-delete-null-pointer-checks. This issue seems conceptually the same as PR96862 which was about -frounding-math breaking some constexpr floating point arithmetic, and we fixed that PR by disabling -frounding-math during manifestly constant evaluation. This patch proposes to do the same for -fno-delete-null-pointer-checks, disabling it during maniestly constant evaluation. I opted to disable it narrowly around the relevant fold_binary call which seems to address all reported constexpr failures, but we could consider it disabling it more broadly as well. PR c++/71962 gcc/cp/ChangeLog: * constexpr.cc (cxx_eval_binary_expression): Set flag_delete_null_pointer_checks alongside folding_cxx_constexpr during manifestly constant evaluation. gcc/testsuite/ChangeLog: * g++.dg/ext/constexpr-pr71962.C: New test. * g++.dg/ubsan/pr71962.C: New test. --- gcc/cp/constexpr.cc | 2 ++ gcc/testsuite/g++.dg/ext/constexpr-pr71962.C | 18 ++++++++++++++++++ gcc/testsuite/g++.dg/ubsan/pr71962.C | 5 +++++ 3 files changed, 25 insertions(+) create mode 100644 gcc/testsuite/g++.dg/ext/constexpr-pr71962.C create mode 100644 gcc/testsuite/g++.dg/ubsan/pr71962.C diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc index 704d936f2ec3..e8426b40c543 100644 --- a/gcc/cp/constexpr.cc +++ b/gcc/cp/constexpr.cc @@ -4068,6 +4068,8 @@ cxx_eval_binary_expression (const constexpr_ctx *ctx, tree t, || TREE_CODE (type) != REAL_TYPE)) { auto ofcc = make_temp_override (folding_cxx_constexpr, true); + auto odnpc = make_temp_override (flag_delete_null_pointer_checks, + true); r = fold_binary_initializer_loc (loc, code, type, lhs, rhs); } else diff --git a/gcc/testsuite/g++.dg/ext/constexpr-pr71962.C b/gcc/testsuite/g++.dg/ext/constexpr-pr71962.C new file mode 100644 index 000000000000..57cb14ac804e --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/constexpr-pr71962.C @@ -0,0 +1,18 @@ +// PR c++/71962 +// { dg-do compile { target c++11 } } +// { dg-additional-options "-fno-delete-null-pointer-checks" } + +struct A { void f(); }; +static_assert(&A::f != nullptr, ""); + +#if __cpp_inline_variables +inline int a, b; +static_assert(&a != &b, ""); +static_assert(&a != nullptr, ""); +#endif + +int main() { + static int x, y; + static_assert(&x != &y, ""); + static_assert(&x != nullptr, ""); +} diff --git a/gcc/testsuite/g++.dg/ubsan/pr71962.C b/gcc/testsuite/g++.dg/ubsan/pr71962.C new file mode 100644 index 000000000000..f17c825da449 --- /dev/null +++ b/gcc/testsuite/g++.dg/ubsan/pr71962.C @@ -0,0 +1,5 @@ +// PR c++/71962 +// { dg-do compile { target c++11 } } +// { dg-additional-options "-fsanitize=undefined" } + +#include "../ext/constexpr-pr71962.C" -- 2.50.0.145.g83014dc05f