This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] c++/60760 - arithmetic on null pointers should not be allowed in constant expressions
- From: Martin Sebor <msebor at gmail dot com>
- To: Jason Merrill <jason at redhat dot com>, Gcc Patch List <gcc-patches at gcc dot gnu dot org>
- Date: Tue, 31 May 2016 16:03:45 -0600
- Subject: Re: [PATCH] c++/60760 - arithmetic on null pointers should not be allowed in constant expressions
- Authentication-results: sourceware.org; auth=none
- References: <573504DD dot 9040707 at gmail dot com> <aed14825-8dd6-9817-3efa-ff963e62aa5f at redhat dot com>
On 05/17/2016 01:44 PM, Jason Merrill wrote:
On 05/12/2016 06:34 PM, Martin Sebor wrote:
Attached is a resubmission of the patch for c++/60760 originally
submitted late in the 6.0 cycle along with a patch for c++/67376.
Since c++/60760 was not a regression, it was decided that it
would be safer to defer the fix until after the 6.1.0 release.
While retesting this patch I was happy to notice that it also
fixes another bug: c++/71091 - constexpr reference bound to a null
pointer dereference accepted.
I'm not sure why we need to track nullptr_p through everything. Can't
we set *non_constant_p instead in the places where it's problematic, as
in cxx_eval_binary_expression?
That would have certainly been my preference over adding another
argument to a subset of the functions, making their declarations
inconsistent. Unfortunately, I couldn't come up with a simpler
way to make it work.
FWIW, my first inclination was to make the nullptr_p flag part
of constexpr_ctx and move the other xxx_p arguments there, to
simplify the interface, until I noticed that all the functions
take a const constexpr_ctx*, preventing them to modify it. It
seemed like too much of a change to fix a bug in stage 3, but
I'd be comfortable making it in stage 1 if you think it's
worthwhile (though my preference would be to do in a separate
commit, after fixing this bug).
I understand that the complication comes because of needing to allow
constexpr int *p = &*(int*)0;
but I don't see how cxx_eval_component_reference could come up with a
constant value for the referent of a null pointer, so we already reject
struct A { int i; };
constexpr A* p = nullptr;
constexpr int i = p->i;
In cxx_eval_indirect_ref, we could check !lval and reject the
constant-expression at that point.
The new code in cxx_eval_component_reference diagnoses the following
problem that's not detected otherwise:
struct S { const S *s; };
constexpr S s = { 0 };
constexpr const void *p = &s.s->s;
Martin