Compile error when not using -ftree-ter

Andrew Haley aph@redhat.com
Wed Aug 18 17:55:00 GMT 2010


On 08/18/2010 05:06 PM, Job Noorman wrote:
> On Tuesday 17 August 2010 22:53:10 you wrote:
>> Job Noorman <jobnoorman@gmail.com> writes:
>>> When I use the "r" constraint, it indeed works and GCC emits the
>>> following
>>>
>>> code:
>>>     movl $_ZN3Foo6foobarEv, %eax
>>>     push %eax;
>>>
>>> What I find strange about this is that GCC has converted
>>> "(plain_foobar_t)&Foo::foobar" in a constant value ($_ZN3Foo6foobarEv)
>>> without using optimizations. So why can't it do the same when using the
>>> "i" constraint?
>>
>> It can, as you can see, but when not optimizing it won't do it reliably
>> before it determines asm constraints.
>>
>> In other words, there is no simple answer to your question, it's just
>> happenstance of how the compiler is written.  It's not a bug, because
>> the compiler only promises to reduce an address to match the "i"
>> constraint when optimizing.

>> ... it's just happenstance of how the compiler is written."
> 
> No offense but I think that's a non-argument. You could use that to reject 
> any bug report.
> 
>> It's not a bug, because the compiler only promises to reduce an address to
>> match the "i" constraint when optimizing.
> 
> Where does it promise that? If that's true, why does something like this 
> always work?:
> 
>     typedef return_type function(args);
>     function func;
> 
>     int main()
>     {
>         asm("push %0" : : "i"((function*)&func));
>     }
> 

Pretty obviously, replacing "movl $_ZN3Foo6foobarEv, %eax; push %rax"
with "push $_ZN3Foo6foobarEv" is an optimization.  It's resonable to
say that gcc only does this optimization if you ask for it.  gcc does
a few constant folding operations anyway, so sometimes this may work,
but I wouldn't rely on it.

> I'm still convinced there is some kind of bug here and I think it has 
> something to do with how GCC handles its PMF to function pointer conversion 
> extension internally.

And nothing that a gcc developer says will convince you otherwise?

If I were you, I'd use

    void test()
    {
        asm("push %0;"
            :
            : "g"((plain_foobar_t)&Foo::foobar));
    }

Andrew.



More information about the Gcc-help mailing list