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?
Martin