Andrew Haley <aph at redhat dot com> wrote: > On 08/18/2010 05:06 PM, Job Noorman wrote: > > On Tuesday 17 August 2010 22:53:10 you wrote: > >> Job Noorman <jobnoorman@xxxxxxxxx> 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. Hi Andrew, > Pretty obviously, replacing "movl $_ZN3Foo6foobarEv, %eax; push %rax" > with "push $_ZN3Foo6foobarEv" is an optimization. Yes, it would be if GCC does it without my help (which, by the way, it does not, no matter which optimizations used). However, since I'm explicitly telling GCC to emit "push $_ZN3Foo6foobarEv", it is an optimization from my side and should have nothing to do with any optimizations from GCC's side. > And nothing that a gcc developer says will convince you otherwise? Nothing a GCC developer has already said has convinced me. Of course I can be convinced. > If I were you, I'd use > > void test() > { > asm("push %0;" > : > : "g"((plain_foobar_t)&Foo::foobar)); > } That will output the exact same assembly code as when using the "r" constraint. I really want to use the "i" constraint to skip the extra "mov". And, sorry if I sound like a broken record, I still think this should be possible. Consider the following (which was pointed out to me in a comment on my bug report): void test() { asm("push %0;" : : "i"((void*)(plain_foobar_t)&Foo::foobar)); } This always works! Now, if you could give me a good explanation of how it could be that "(void*)expr" is accepted as a constant expression when "expr" is not, I might be convinced that this is not a bug. Job