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