[cfe-dev] clang trunk: extern "C"/static problem

John McCall rjmccall at apple.com
Fri Mar 15 00:48:33 PDT 2013

On Mar 14, 2013, at 8:46 PM, Richard Smith <richard at metafoo.co.uk> wrote:
> On Thu, Mar 14, 2013 at 6:27 PM, John McCall <rjmccall at apple.com> wrote:
> On Mar 14, 2013, at 5:59 PM, Richard Smith <richard at metafoo.co.uk> wrote:
>> On Thu, Mar 14, 2013 at 10:00 AM, John McCall <rjmccall at apple.com> wrote:
>> On Mar 14, 2013, at 8:14 AM, "Richtarsky, Martin" <martin.richtarsky at sap.com> wrote:
>> > Hi Rafael,
>> >
>> > in this case the affected function is called from another function which is implemented in inline assembler, within the extern "C" scope.
>> Ah, you know, I can't believe we didn't think about inline assembly when we were enumerating potential places where this would bite us.  Too fixated on the JIT case, I suppose.
>> We did think about it (although I'm not sure whether that made it to the list); in fact, this happened in some cases inside LLVM.
> I do not remember it coming up about inline assembly.  I remember it coming up about dynamic symbol lookups, and we were willing to wave our hands about those because there is very little code in the world that does this sort of symbol lookup into the enclosing process.  I am not willing to hand-wave away inline assembly.
> Considering dynamic linking seems a bit strange; we were only ever talking about internal linkage functions.

Hmm;  I was remembering that there was a platform where dlsym searched internal-linkage functions based on call site, but I think I'm just flat-out wrong.

>> Our conclusion was: if you want to use a function from inline asm, you should use an asm label on that function, otherwise it might get mangled unexpectedly. This is true independent of the static/extern "C" issue, due to some platforms prepending an underscore to symbol names, etc.
> Conveniently enough, inline assembly usually can't be shared between platforms that do Pascal mangling and those that don't, because significantly different platforms usually have significantly different compilers and with significantly different inline assembly syntax.
> Inconveniently, we have to cope with exactly that when we call into the problematic symbols in llvm/lib/Target/X86/X86JITInfo.cpp (this is what the message I quoted above was referring to). Search for calls to LLVMX86CompilationCallback2, and note the ASMPREFIX hack.

Okay, so projects that care about platform portability already have workarounds for this, but:
  - many projects don't currently care about platform portability and
  - most projects that do will already have perfectly functioning workarounds using __USER_LABEL_PREFIX__ because
  - projects have to use __USER_LABEL_PREFIX__ anyway if they want to use library functions.

So basically, all such projects should have yet another (subtle) obstacle to porting to clang just so that we can conform to the standard in the same way as AFAICT precisely one other compiler which happens to be famously pedantic.  All of this is in an area where there's already massive and permanent non-conformance, because the standard's interest in allowing overloaded static extern "C" functions is to make it easier to define functions whose function type has C language linkage.

>  What you're doing is making it more awkward to port inline assembly between compilers on the *same* platform by introducing a totally spurious hurdle, based on a line from the standard that's inconsistent with an overwhelmingly dominant existing practice.
> I don't agree that g++ counts as "overwhelmingly dominant existing practice",

g++ and MSVC and probably every other compiler in the world except apparently EDG.  That would be EDG, the compiler whose authors took it as a point of pride to spend several programmer-years implementing template export.

The C++ committee is very bad about standardizing existing practice instead of just making things up to serve their own fantasies.  It's a serious problem.  It doesn't mean we should ignore everything they say, but yes, I think it means we have to actually consider things before just implementing them as specified.  The fact that we usually do is pretty well evidenced by the number of DRs we've authored.

> especially given that EDG does not follow g++ here in its g++-compatible mode.

Yeah, I somehow suspect EDG not being fully compatible with g++ in its g++-compatible mode is considered a bug over in New Jersey, not some deeply principled stand.

Can you find any compilers besides EDG that mangle static symbols within extern "C"?

> This would not be the first g++ bug which people have come to rely on, which we could support at the expense of being subtly non-conforming, but choose not to. Plus, there is a simple, trivial fix to the offending code which allows it to be accepted by us, g++, and EDG.

It would also not be the first GCC quirk that we emulated because we saw no real value in deviating.  We didn't *have* to implement GCC's weird bitfield promotion rules.  We didn't *have* to copy that bizarre thing where GCC passes part of a union in the upper half of an SSE register.  We *could* have implemented the actual C++ rules about function types with language linkage.

We chose to fight users about the template model because we saw value in implementing the model as specified and because GCC's model was badly enough broken that it would have seriously interfered with reasonable extension (and they have since gotten much better).  We implemented C++11 as specified because it was new and therefore a chance to start afresh.  I do not think these things mean that we're ready to go to the barricades over every last piece of minutia.

> I think the right question is, is this a battle worth fighting? Is one inconvenienced user enough that we should give up any hope of ever conforming in this area?

Given that most people are not, in fact, randomly recompiling their code with a top-of-tree clang several months before the next open-source release, two known inconvenienced users in two weeks seems pretty significant to me.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20130315/5ffbc323/attachment.html>

More information about the cfe-dev mailing list