This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] Fix constexpr evaluation of comparisons involving pointer-to-members
- From: Patrick Palka <patrick at parcs dot ath dot cx>
- To: Jason Merrill <jason at redhat dot com>
- Cc: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Date: Thu, 4 Feb 2016 12:40:50 -0500
- Subject: Re: [PATCH] Fix constexpr evaluation of comparisons involving pointer-to-members
- Authentication-results: sourceware.org; auth=none
- References: <1450739227-18825-1-git-send-email-patrick at parcs dot ath dot cx> <56B0FAA2 dot 3080804 at redhat dot com> <alpine dot DEB dot 2 dot 20 dot 9 dot 1602031242530 dot 1505 at idea> <56B35F0A dot 5090008 at redhat dot com> <CA+C-WL9ysU-n-+Kc94Kv_gfNsi2DG0BWV63vA4Eu8ax4wWJS_g at mail dot gmail dot com> <56B382FE dot 2030904 at redhat dot com> <CA+C-WL8Nj311=A+AdmnYrLwnKcOgHGjvHNdTwewyZz0uHJ7uVg at mail dot gmail dot com>
On Thu, Feb 4, 2016 at 12:24 PM, Patrick Palka <patrick@parcs.ath.cx> wrote:
> On Thu, Feb 4, 2016 at 11:57 AM, Jason Merrill <jason@redhat.com> wrote:
>> On 02/04/2016 10:32 AM, Patrick Palka wrote:
>>>
>>> On Thu, Feb 4, 2016 at 9:24 AM, Jason Merrill <jason@redhat.com> wrote:
>>>>
>>>> On 02/03/2016 12:51 PM, Patrick Palka wrote:
>>>>>
>>>>>
>>>>> + && (integer_minus_onep (lhs)
>>>>> + || integer_minus_onep (rhs)))
>>>>
>>>>
>>>>
>>>> Let's use null_member_pointer_value_p here.
>>>
>>>
>>> Done.
>>>
>>>>
>>>> Please add pointers to member functions to the testcase.
>>>
>>>
>>> This does not currently work properly because comparisons between
>>> distinct pointers to (non-virtual) member functions eventually perform
>>> a comparison between two distinct FUNCTION_DECLs, and fold_binary_loc
>>> currently does not fold away such comparisons. So any static_asserts
>>> that perform comparisons between distinct function pointers or between
>>> distinct pointers to (non-virtual) member functions fail with
>>> "non-constant condition for static assertion". (Comparisons between
>>> pointers to distinct virtual member functions _do_ work because in
>>> that case we are ultimately just comparing integer offsets, not
>>> FUNCTION_DECLs. And comparisons between equivalent pointers trivially
>>> work.)
>>>
>>> I think the problem may lie in symtab_node::equal_address_to, which
>>> apparently returns -1, instead of 0, for two obviously distinct
>>> FUNCTION_DECLs.
>>
>>
>> Right, because they might be defined as aliases elsewhere. But it looks
>> like it should work if you define f and g.
>
> That makes sense. But even when I define f and g, the comparisons
> don't get folded away:
>
> #define SA(x) static_assert ((x), #x)
>
> void f () { }
> void g () { }
>
> struct X { int a, b; void f (); void g (); };
>
> void X::f () { }
> void X::g () { }
>
> void
> foo ()
> {
> SA (&f != &g);
> SA (&X::f != &X::g);
> }
>
> bool bar = &f != &g;
>
> Although the static_asserts fail, the initialization of the variable
> bar _does_ get folded to 1 during gimplification. When evaluating the
> static_asserts, symtab_node::equal_address_to again returns -1 but
> during gimplification the same call to symtab_node::equal_address_to
> returns 0. So probably the symbols are not fully defined yet in the
> symbol table at the point when we are evaluating the static_asserts.
Indeed, symtab_node::equal_address_to returns 0 only if both symbols
have their ->analyzed flag set. But cgraph_node::analyze() (which
sets the analyzed flag) is called during finalization of the
compilation unit -- obviously not in time for the static_asserts to
get folded.