On Wed, Jul 20, 2016 at 2:15 PM, Martin Sebor <mse...@gmail.com> wrote: > On 07/20/2016 07:52 AM, Jason Merrill wrote: >> >> On Mon, Jul 18, 2016 at 6:15 PM, Martin Sebor <mse...@gmail.com> wrote: >>> >>> On 07/18/2016 11:51 AM, Jason Merrill wrote: >>>> >>>> >>>> On 07/06/2016 06:20 PM, Martin Sebor wrote: >>>>> >>>>> >>>>> @@ -2911,6 +2923,14 @@ cxx_eval_indirect_ref (const constexpr_ctx >>>>> *ctx, tree t, >>>>> if (*non_constant_p) >>>>> return t; >>>>> >>>>> + if (integer_zerop (op0)) >>>>> + { >>>>> + if (!ctx->quiet) >>>>> + error ("dereferencing a null pointer"); >>>>> + *non_constant_p = true; >>>>> + return t; >>>>> + } >>>> >>>> >>>> I'm skeptical of checking this here, since *p is valid for null p; &*p >>>> is even a constant expression. And removing this hunk doesn't seem to >>>> break any of your tests. >>>> >>>> OK with that hunk removed. >>> >>> >>> With it removed the constexpr-nullptr-2.C test fails on line 64: >>> >>> constexpr const int *pi0 = &pa2->pa1->pa0->i; // { dg-error "null >>> pointer|not a constant" } >>> >>> Here, pa2 and pa1 are non-null but pa0 is null. >> >> >> It doesn't fail for me; that line hits the error in >> cxx_eval_component_reference. I'm only talking about removing the >> cxx_eval_indirect_ref hunk. > > > Sorry, I may have been referring to an older patch. With the latest > patch, the assertion is on line 75. It's also not failing, even > though it should be. The problem is that I had misunderstood how > the vertical bar in DejaGnu directives works. I thought it meant > that both sides had to match a message on that line, when it means > only one side has to. I'll need to fix that (how does one match > two messages on the same line?) > > But removing the hunk as you suggest does break the intent of the > test. With it there, we get a descriptive message for the invalid > code below clearly explaining the problem: > > $ cat xyz.c && /build/gcc-60760/gcc/xgcc -B /build/gcc-60760/gcc -S -Wall > -Wextra -Wpedantic -xc++ xyz.c > struct S { const S *p; int i; }; > > constexpr S s0 = { 0, 0 }; > constexpr S s1 = { &s0, 1 }; > > constexpr int i = s1.p->p->i; > xyz.c:6:28: error: dereferencing a null pointer > constexpr int i = s1.p->p->i; > ^ > > With the hunk removed, all we get is the generic: > > xyz.c:6:28: error: ā*(const S*)((const S*)s1.S::p)->S::pā is not a constant > expression > constexpr int i = s1.p->p->i; > ^ > > Re-reading your comment above now: "since *p is valid for null p;" > I agree that &*p is valid when p is null. Unless I missed a case > it is accepted with or without the hunk. Otherwise, *p is not valid, > and it is also rejected with or without it. > > Is there something else you're worried about with the hunk that > makes you want to trade it off for the less informative message?
OK, we can keep the hunk, but only when !lval, since that means we access the value. Jason