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
> 

Reply via email to