<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On 1 May 2018 at 21:56, Evan Driscoll via cfe-dev <span dir="ltr"><<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><span class="">On Tue, May 1, 2018 at 11:43 PM, Evan Driscoll <span dir="ltr"><<a href="mailto:evaned@gmail.com" target="_blank">evaned@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div><div><div><div><div><div>  $ cat huh.cc<br>  extern "C" {<br>    static __attribute__((used)) void dummy1(int x) { }<br>  }<br>  $ clang -c huh.cc && nm huh.o<br>  0000000000000000 t f<br>  0000000000000000 t _ZL1fi<br>  $ clang -c huh.cc && nm huh.o | c++filt<br>  0000000000000000 t f<br>  0000000000000000 t f(int)<br></div></div></div></div></div></div></div></blockquote></span><div><br>In the interest of hopefully eliminating confusion -- sorry for the 
output not exactly matching up with the examples in terms of function 
names. I was working half in Compiler Explorer and half with a file on a
 local file system. I noticed as I was finishing the email, and thought I'd try to align the names by editing the command output to match... but of course that is always a bad idea. :-)<br><br></div><div>Anyway, of course that code doesn't produce an object file with a symbol 'f' in it, it'd be 'dummy1'. The presence of both the unmangled and mangled symbols is the same though.</div></div></div></div></blockquote><div><br></div><div>In C++, extern "C" means two different things:</div><div><br></div><div>1) All[*] function types within the region are given C language linkage (which means they use the C calling convention). In GCC and Clang, the C calling convention is the same as the C++ calling convention, so this doesn't really matter (and actually isn't implemented at all, which is slightly non-conforming).</div><div>2) All[*] function and variable declarations *with external linkage* within the region are given C language linkage (which means they use the C symbol names).</div><div><br></div><div>Point 2 is the relevant one here, and the key fact is that it only applies to functions with external linkage. In particular, this is valid:</div><div><br></div><div>extern "C" {</div><div>  static void f(int) {}</div><div>  static void f(double) {}</div><div>}</div><div><br></div><div>... and the two functions do not collide per the standard C++ rules.</div><div><br></div><div>However, GCC historically did not implement this rule that way (and as far as I know, still doesn't), and applies the C language linkage rules even to internal linkage functions.</div><div><br></div><div>Clang chooses to try to satisfy both the goal of C++ standard conformance and GCC compatibility, and the way it does that is to use two different mangled names for such internal-linkage-in-extern-C blocks: a C++ one (allowing overloading), and a C alias; the latter is omitted in the case where it would collide with another symbol (which effectively means we try to emit it only after we emit everything else).</div><div><br></div><div>I would guess the problem is that we check that the referent of __attribute__((alias(...))) exists before we register the static extern "C" aliases, which is why the lookup is failing.</div><div><br></div><div><br></div><div> [*]: Irrelevant exceptions elided</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><span class="HOEnZb"><font color="#888888"><div>Evan<br></div></font></span><span class=""><div><br><br> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div><div><div><div><div><div><br></div><br></div>So I tried using the mangled name in the alias, and that works:<br><br>  extern "C" {<br>    static __attribute__((used)) void f1 () {}<br>    void f () __attribute__ ((weak, alias("_ZL2f1v"))); // OK<br>  }<br><br></div>and of course then so does this<br><br>  static __attribute__((used)) void f1 () {}<br>  extern "C" {<br>    void f () __attribute__ ((weak, alias("_ZL2f1v")));<br>  }<br><br><br></div>Furthermore, if I browse the Itanium ABI page, I can't even figure out how you get a "_ZL..." mangled symbol, but I'm sure I'm missing something (e.g. c++filt demangles it fine...)<br></div></div></div></blockquote></span></div></div></div></blockquote><div><br></div><div>_ZL is a GCC mangling extension used to mangle the names of internal-linkage symbols. Because it's only used for internal-linkage symbols, it's not part of the ABI per se, but it's still useful for us to use the same scheme so that demanglers can produce proper output for our names. (Historically, C++ allowed some weird constructs where you could have two distinct symbols, one with internal linkage and one with external linkage, that would mangle the same, named in the same translation unit, so a disambiguator was needed. Such cases are now ill-formed, but the legacy of that remains in our mangling scheme.)</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><span class=""><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div><div></div>Anyway, I can easily work around this is my actual code, but how much of this is expected behavior?</div></div></blockquote></span></div></div></div></blockquote><div><br></div><div>Everything except the actual error is expected behavior. For GCC compatibility, I think we should try to accept examples such as yours. Interested in putting together a patch?</div></div></div></div>