On Thu, 2020-01-23 at 14:59 -0700, Sandra Loosemore wrote: > On 1/23/20 1:17 PM, Jeff Law wrote: > > On Tue, 2020-01-21 at 15:00 -0700, Sandra Loosemore wrote: > > > In doing some nios2-elf testing, I ran into a bunch of failures in > > > constexpr-related tests in the C++ testsuite. This target defaults to > > > -fno-delete-null-pointer-checks at the request of Altera/Intel, in order > > > to support some of their BSPs where 0 is a legitimate memory address. > > > Some other bare-metal targets also default to > > > -fno-delete-null-pointer-checks. > > > > > > This patch makes the dependence of these tests on > > > -fdelete-null-pointer-checks explicit. I've previously fixed some other > > > tests that failed on nios2-elf in the same way so this is borderline > > > obvious, but it's a little troubling to me that the correct semantics of > > > some of these testcases seems to depend on what we document in the > > > manual as an optimization option. :-S Maybe there is some other bug > > > here? > > > > > > Anyway, if nobody has any objections or better ideas, I will go ahead > > > and commit this in a few days. > > It'd be nice to know why that flag matters for constexpr. But I've got > > no problem with the change itself. > > I haven't looked at all of the failing tests in detail, but the ones I > did peek at all seemed to be related to constant-folding pointer > comparisons against null. > > The thing that nags at me is that e.g. in g++.dg/cpp0x/constexpr-odr1.C > we have: > > template<int> struct A { > static const bool x; > static_assert(&x, ""); // odr-uses A<...>::x > }; > > int g; > > template<int I> > const bool A<I>::x = (g = 42, false); > > void f(A<0>) {} // A<0> must be complete, so is instantiated > int main() > { > if (g != 42) > __builtin_abort (); > } > > Whether or not this is valid code depends on whether "&x != 0" can be > constant-folded. Without -fdelete-null-pointer-checks, g++ says: > > /path/to/g++.dg/cpp0x/constexpr-odr1.C: > In instantiation of 'struct A<0>': > /path/to/g++.dg/cpp0x/constexpr-odr1.C:14:12: > required from here > /path/to/g++.dg/cpp0x/constexpr-odr1.C:6:17: > error: non-constant condition for static assertion > /path/to/g++.dg/cpp0x/constexpr-odr1.C:12:12: > error: '((& A<0>::x) != 0)' is not a constant expression > > So is -fdelete-null-pointer-checks really an optimization option, or a > language semantics option? It's an optimization option, pure and simple.
But determining if an expression is a constant sometimes requires folding (as in this case). Normally folding will assume that the address of an object can't be zero. -fno-delete-pointer-checks turns off that assumption (as it should). > > BTW, here's Altera's original description of the over-eager optimization > problems they were trying to work around: Yea. Using -fno-delete-pointer-checks is the right thing for them to do in their case. > https://gcc.gnu.org/ml/gcc/2015-02/msg00163.html >