[PATCH] Fix constexpr evaluation of comparisons involving pointer-to-members

Patrick Palka patrick@parcs.ath.cx
Thu Feb 4 17:25:00 GMT 2016


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.



More information about the Gcc-patches mailing list