On Mar 23, 2018, Jason Merrill <ja...@redhat.com> wrote: > On Fri, Mar 23, 2018 at 4:55 PM, Jason Merrill <ja...@redhat.com> wrote: >> On Fri, Mar 23, 2018 at 12:44 PM, Jason Merrill <ja...@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