On 4/26/21 3:05 PM, Patrick Palka wrote:
On Mon, 26 Apr 2021, Jason Merrill wrote:
On 4/26/21 12:17 PM, Patrick Palka wrote:
During constexpr evaluation, a base-to-derived conversion may yield an
expression like (Derived*)(&D.2217.D.2106 p+ -4) where D.2217 is the
derived object and D.2106 is the base. But cxx_fold_indirect_ref
doesn't know how to resolve an INDIRECT_REF thereof to just D.2217,
because it doesn't handle POINTER_PLUS_EXPRs of a COMPONENT_REF and
negative offset well: when the offset N is positive, it knows that
'&x p+ N' is equivalent to '&x.f p+ (N - bytepos(f))', but it doesn't
know about the reverse transformation, that '&x.f p+ N' is equivalent
to '&x p+ (N + bytepos(f))' when N is negative, which is important for
resolving such base-to-derived conversions and for accessing subobjects
backwards. This patch teaches cxx_fold_indirect_ref this reverse
transformation.
Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for
trunk?
OK. Do you think it's worth doing this in fold-const.c:fold_indirect_ref_1 as
well?
Hmm, I'm not sure. The function comment for cxx_fold_indirect_ref says
"Also we want to allow folding to COMPONENT_REF, which would cause
trouble with TBAA in fold_indirect_ref_1", presumably referring to the
folding of '*(&x p+ N)' to 'x.f', so I suppose the reverse folding
'*(&x.f p+ -N)' to 'x' might be problematic for similar reasons. But
I'm not sure why the first folding is problematic for TBAA in the first
place.
Hmm, I don't remember what the issue was. I suppose in general changing
between referring to a subobject and a containing object changes which
types could be aliased, but I don't know how that would be a problem
given that we know we're looking for an object of a particular type at a
particular offset.
But consistency with that does seem like a reason not to make this
change there as well.
Jason