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
>