Compile error when not using -ftree-ter

Job Noorman jobnoorman@gmail.com
Thu Aug 19 13:03:00 GMT 2010


On Thursday 19 August 2010 13:24:49 you wrote:
> On 08/19/2010 11:33 AM, Job Noorman wrote:
> > On Thursday 19 August 2010 11:19:09 you wrote:
> >> On 08/19/2010 09:10 AM, Job Noorman wrote:
> >>> Andrew Haley <aph at redhat dot com> wrote:
> >>>> 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.
> >> 
> >> "should" statement with missing "because": syntax error.  :-)
> >> 
> >>>> 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".
> >> 
> >> Works for me:
> >> 
> >> -O0:
> >>        movl    $_ZN3Foo6foobarEv, %eax
> >> 
> >> #APP
> >> # 13 "ttt.cc" 1
> >> 
> >>         push %rax;
> >> 
> >> # 0 "" 2
> >> #NO_APP
> >> 
> >> -O2:
> >> 
> >> #APP
> >> # 13 "ttt.cc" 1
> >> 
> >>         push $_ZN3Foo6foobarEv;
> >> 
> >> # 0 "" 2
> >> #NO_APP
> >> 
> >>> 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 already did, I think: some things get constant folded regardless of
> >> optimization level, but this is just luck.
> >> 
> >>> I might be convinced that this is not a bug.
> >> 
> >> But gcc doesn't support the "i" constraint with anything other than a
> >> real compile-time constant (in the sense of __builtin_constant_p) so
> >> it's not a bug.
> > 
> > Hi Andrew,
> 
> Hi,
> 
> > About your last statement: That would make sense to me. (Although I
> > really don't like the fact that whether something would be accepted by
> > the "i" constraint depends on optimization options. IMHO, whether
> > something is syntactically valid should not depend on optimizations.)
> 
> It's not syntactically invalid, it's semantically invalid.  It's
> always semantically invalid.
> 
> > But I see some evidence that your statement is not true. First of all,
> > it's not what the documentation claims:
> > 
> > " 'i': An immediate integer operand (one with constant value) is allowed.
> > This includes symbolic constants whose values will be known only at
> > assembly time or later. "
> 
> Hmm, this seems to generalize "i" to symbolic constants, but not to
> expressions that yield addresses.
> 
> > Secondly, in practice a lot of expression are accepted which are not
> > 
> > __builtin_constant_p. Here is an example program:
> >     #include <iostream>
> >     using namespace std;
> >     
> >     struct Foo {void foobar() {}};
> >     typedef void (*plain_foobar_t)(Foo*);
> >     void func() {}
> >     int var;
> >     
> >     int main()
> >     {
> >     
> >         cout <<
> >         __builtin_constant_p((void*)(plain_foobar_t)(&Foo::foobar))
> >         
> >             << __builtin_constant_p(func)
> >             << __builtin_constant_p(&var) << endl;
> >         
> >         asm("" : : "i"((void*)(plain_foobar_t)(&Foo::foobar)),
> >         
> >                 "i"(func),
> >                 "i"(&var));
> >     
> >     }
> > 
> > This compiles without errors at -O0 but prints "000".
> > 
> > So, if your statement is true, don't you think there is something weird
> > going on here?
> 
> This is a fundamental part of language definition: a translator is not
> required to do anything in particular with a program that has
> undefined behaviour.  One of the options a translator has is to do
> what the user expected.
> 
> Sometimes an operand that is not a constant may work with the "i"
> constraint.  This is because a pass in gcc propagated a constant
> through an expression.  gcc is allowed to do this.  However, gcc is
> not required to do this.
> 
> Finally, does the "g" constraint really not work for you with a recent
> gcc?
> 
> Andrew.

<Please ignore my previous message. Something went wrong when trying to reply 
and this is the real reply>

Hi Andrew,

> Finally, does the "g" constraint really not work for you with a recent
> gcc?

It does work. I just forgot to reply on that in my last mail :-)

> Hmm, this seems to generalize "i" to symbolic constants, but not to
> expressions that yield addresses.

> ... a translator is not required to do anything in particular with a program 
> that has undefined behaviour.

So basically you are saying that passing an expression that yields an address 
to an "i" constraint results in undefined behavior? Well, then I think it makes 
sense to me that this is not a bug :-)

One thing, however: My interpretation of the sentence

"This includes symbolic constants whose values will be known only at assembly 
time or later."

is that it is allowed to pass "address constant expressions" (5.19.4 of the 
C++ standard) because they will be resolved to constants "at assembly time or 
later" (at link time).

Is this a misinterpretation? Of not, maybe the documentation could be 
clarified.

Job




More information about the Gcc-help mailing list