[cfe-dev] time of inline assembler evaluation in template specialization

Titus von Boxberg titus at v9g.de
Fri Jun 24 06:09:44 PDT 2011


Am Fr, 24.06.2011, 11:51 schrieb Sebastian Redl:
> On 24.06.2011 10:09, Titus von Boxberg wrote:
>> There is no "ill formed", "invalid" or whatsoever bad C++ code in my example.
> There is ill-formed use of a GCC/Clang extension: you have a clobber
> list that contains registers not valid for the current platform. The
> fact that it happens to be in an inline function of a template
> specialization is irrelevant here.
No, it is relevant here because that's the use case.

>
>> It's like in any template instantiation / specialization.
>> It only works because the right (specialized) template code gets selected and emitted.
> That's not how templates work.
How else should they work?
std::copy is perfectly valid until I instantiate it with e.g. an int instead of
something which has an interface of an iterator.
Analogous to this code.

>> There is no standard for inline asm,
> Yes, there is. It's just that this particular form is an extension of
> the standard form.
The standard I'm aware of says
"The asm declaration is conditionally-supported; its meaning is implementation-defined."
which I - admittedly - shortened to "there is no standard".
What standard do you mean?

> More precisely, GCC only validates the asm constraints when actually
> generating code. It has nothing to do with templates. The only
> interesting thing happening here is that GCC doesn't emit the code for
> the inline function if it isn't used.
Same with clang. It does not emit code for the unused template specialization.
Otherwise it would/could detect that "ldr r4,=1" is invalid for x86 assembler.
And, of course, it has to do with templates because this is my use case, and one
of the few use case I'm aware of where code analysis and code generation fall
that "far" apart.

> Asm constraints are a compiler extension. Why shouldn't the compiler
> frontend validate them? Because they are in strings? Consider this:
> extern "FooBar" void f();
> Should the compiler not complain about this function unless it is used?
To again quote from the standard (I'm aware of):
"Use of a string-literal other than "C" or "C++" is conditionally supported,
with implementation-defined semantics."
If the compiler magically (!) knows already during syntax analysis that "C" is the only
external linkage spec supported, then it *might* ("implementation-defined")
bail out at this stage.
If your fancy super OS happens to have a "COBOL" or even "FooBar" standard,
whatever that might be, porting clang to this OS would mean to make
it emit code with this linkage standard.
In short, yes, I'd rather see it not as part of the fsyntax-only check.
That's why I guess this is a string constant: to mark it as "beyond of C++"
or "implementation defined".
Same in asm statements. Here, clang is not ported but should be constructed
compatible with gcc.

>> All I want to say is:
>> Doing it the gcc way is what I'd suggest for clang.
> So you don't want to know about bad asm constraints if you just run an
> -fsyntax-only check over the file? Because that's what delaying the
> check to code generation means. Well, I want to get an error then. So I
> vote for not delaying the check.
You're not really trying to tell me that an intended use
case of clang is to fsyntax-only-check asm() register declarations?
With gcc -fsyntax-only, this is not possible, anyway:
int main(void)
{
  register int	a=1, b=2;
  asm("xor %1,%0\n\t" : "=&r"(b) : "r"(a) : "blah");
  return b;
}

goes very well through gcc. BUT g++ -fsyntax-only:

  asm("xor %1,%0\n\t" : "=&r"(blah) : "r"(a) : "eax");

gets the right error
asmtst2.cpp: In function ‘int main()’:
asmtst2.cpp:5: error: ‘blah’ was not declared in this scope
asmtst2.cpp:5: error: lvalue required in asm statement
asmtst2.cpp:5: error: invalid lvalue in asm output 0

And exactly this is the behaviour I'd recommend
to make clang compatible with. It is consistent because
what can be analyzed with a syntax check on "C++ level"
get's done, and *all* of the rest goes to code generation phase.
And I expect that to be less "hard to implement" than
making it consistent the other way round.

>> The sense to accept this code is because one gains the option of
>> using template specialization instead of having to rely on the preprocessor
>> to select the right (assembly) code which is perfectly reasonable.
> What makes the preprocessor a worse choice than templates here?
First, this is a matter of taste, and thus is not really an argument.
Second because there *is* existing code which relies on gcc's (consistent)
different levels of inline assembly checking.
It can be compared to Stroustrup's known dislike of the preprocessor but
- of course - keeping it in the language definition.





More information about the cfe-dev mailing list