[PATCH] [PR c++/84943] allow folding of array indexing indirect_ref

Alexandre Oliva aoliva@redhat.com
Wed Mar 28 06:31:00 GMT 2018


On Mar 23, 2018, Jason Merrill <jason@redhat.com> wrote:

> On Fri, Mar 23, 2018 at 4:55 PM, Jason Merrill <jason@redhat.com> wrote:
>> On Fri, Mar 23, 2018 at 12:44 PM, Jason Merrill <jason@redhat.com> wrote:
>>> Seems like cp_fold should update CALL_EXPR_FN with "callee" if non-null.
>> 
>> Did you try this?  That should avoid it being ADDR_EXPR of a decl.

> Oh, I was assuming the ICE was in the middle-end, but it's in
> build_call_a.  And it looks like the problem isn't that it's an
> ADDR_EXPR of a decl, but that the function isn't marked TREE_USED.

Well, yeah.  cp_build_function_call_vec marks the function as used when
function is a FUNCTION_DECL.  In this testcase, it's INDIRECT_REF of
ADDR_EXPR of FUNCTION_DECL.  Since the idea of bypassing cancelling-out
pairs of INDIRECT_REF and ADDR_EXPR, that would have allowed
cp_build_function_call_vec to get to the FUNCTION_DECL and mark it as
used was not accepted, the alternative was to stop build_call_a from
getting to the FUNCTION_DECL, which was very much in line of what you'd
said about preserving source constructs and allowing the significant
differences for some language rules to remain in place.

Now, to me, it is clear that if we are to preserve source level
constructs because they could make some significant different WRT
certain language rules, and to that end we don't want to simplify the
INDIRECT_REF arising from the array indexing with the ADDR_EXPR of the
function-to-pointer decay, then it should follow that we also don't want
to simplify the ADDR_EXPR that build_addr_func would introduce with that
INDIRECT_REF.  That's what the latest patch I proposed does, and it also
solves the potential inconsistency between cp_build_function_call_vec
and build_call_a, in which one of them does not find the FUNCTION_DECL
because it's too deeply hidden within INDIRECT_REFs/ADDR_EXPRs pairs and
so it fails to mark the decl as used, but then the other finds it
because build_addr_func peeled an INDIRECT_REF, and then complains that
the decl is not marked as used.

Now, I don't know what the rules are that could make a difference in
this case, but I must confess that I'm a bit surprised that the
following constructs could possibly be interpreted differently under C++
rules:

  f();
  (&f)();
  (*f)();
  f[0]();
  (*&f)();
  (*&*&*&f)();

Maybe they aren't when we get to cp_build_function_call_vec (any
differences WRT overload resolution would have been taken care of), and
we should use get_callee_fndecl in cp_build_function_call_vec, and
arrange for get_callee_fndecl to peel as many layers of INDIRECT_REF and
ADDR_EXPR as it finds when searching for a FUNCTION_DECL.

Anyway, given the accumulated constraints I've been given WRT to this
bug, I'm afraid I've run out of ideas.  I welcome suggestions as to how
to proceed.

-- 
Alexandre Oliva, freedom fighter    http://FSFLA.org/~lxoliva/
You must be the change you wish to see in the world. -- Gandhi
Be Free! -- http://FSFLA.org/   FSF Latin America board member
Free Software Evangelist|Red Hat Brasil GNU Toolchain Engineer



More information about the Gcc-patches mailing list