<div dir="ltr"><div dir="ltr">On Wed, 5 May 2021 at 10:57, Nathan Sidwell <<a href="mailto:nathan@acm.org">nathan@acm.org</a>> wrote:<br></div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">On 5/5/21 1:37 PM, Richard Smith wrote:<br>
> On Mon, 3 May 2021 at 10:36, Nathan Sidwell via cfe-dev <br>
> <<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a> <mailto:<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>>> wrote:<br>
> <br>
>     On 5/3/21 12:42 PM, David Blaikie via cfe-dev wrote:<br>
>      ><br>
>      ><br>
>      > On Mon, May 3, 2021 at 4:10 AM Nathan Sidwell via cfe-dev<br>
>      > <<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a> <mailto:<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>><br>
>     <mailto:<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a> <mailto:<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>>>> wrote:<br>
>      ><br>
>      >     On 4/30/21 1:52 PM, Fāng-ruì Sòng via cfe-dev wrote:<br>
>      >      > Redirect to cfe-dev.<br>
>      >      ><br>
>      >      > On Fri, Apr 30, 2021 at 9:42 AM Xun Li via llvm-dev<br>
>      >      > <<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a> <mailto:<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>><br>
>     <mailto:<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a> <mailto:<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>>>><br>
>     wrote:<br>
>      >      >><br>
>      >      >> Hi,<br>
>      >      >><br>
>      >      >> I noticed that when compiling lambda functions, the generated<br>
>      >     function<br>
>      >      >> names use different conventions than GCC.<br>
>      >      >> Example: <a href="https://godbolt.org/z/5qvqKqEe6" rel="noreferrer" target="_blank">https://godbolt.org/z/5qvqKqEe6</a><br>
>     <<a href="https://godbolt.org/z/5qvqKqEe6" rel="noreferrer" target="_blank">https://godbolt.org/z/5qvqKqEe6</a>><br>
>      >     <<a href="https://godbolt.org/z/5qvqKqEe6" rel="noreferrer" target="_blank">https://godbolt.org/z/5qvqKqEe6</a><br>
>     <<a href="https://godbolt.org/z/5qvqKqEe6" rel="noreferrer" target="_blank">https://godbolt.org/z/5qvqKqEe6</a>>><br>
>      >      >> The lambda in Clang is named "_Z3barIZ3foovE3$_0EvT_",<br>
>     while the one<br>
>      >      >> in GCC is named "_Z3barIZ3foovEUlvE_EvT_". Their<br>
>     demangled names are<br>
>      >      >> also different ("void bar<foo()::$_0>(foo()::$_0)" vs "void<br>
>      >      >> bar<foo()::{lambda()#1}>(foo()::{lambda()#1})").<br>
>      >      >> Lambdas are not covered by the ABI so this is OK.<br>
>      ><br>
>      >     Actually, they are.  See 5.1.8 of the ABI doc<br>
>      >     (<a href="https://github.com/itanium-cxx-abi/cxx-abi" rel="noreferrer" target="_blank">https://github.com/itanium-cxx-abi/cxx-abi</a><br>
>     <<a href="https://github.com/itanium-cxx-abi/cxx-abi" rel="noreferrer" target="_blank">https://github.com/itanium-cxx-abi/cxx-abi</a>><br>
>      >     <<a href="https://github.com/itanium-cxx-abi/cxx-abi" rel="noreferrer" target="_blank">https://github.com/itanium-cxx-abi/cxx-abi</a><br>
>     <<a href="https://github.com/itanium-cxx-abi/cxx-abi" rel="noreferrer" target="_blank">https://github.com/itanium-cxx-abi/cxx-abi</a>>>)<br>
>      ><br>
>      >     The reason is that these symbols do escape into object files with<br>
>      >     external linkage (not something originally anticipated).<br>
>      ><br>
>      ><br>
>      > Could you provide a quick example of this ABI break (where two files<br>
>      > compiled with matching compiler (GCC or Clang) link/run<br>
>     correctly, but<br>
>      > mismatching in either direction fails to link/run correctly)?<br>
> <br>
>     hm, it turned out to be not quite the case I was thinking of:<br>
> <br>
>     // header.h<br>
>     template<typename T> int bar (T) {static int i; return i++; }<br>
> <br>
>     // the following lambda is attached to 'ctr', and therefore the<br>
>     // same type in every TU, you need gcc >= 10 to get this right.<br>
>     // not sure if clang models that correctly (given the template<br>
>     // mangling bug).  And yes, this idiom exists in header files<br>
>     // -- I'm looking at you, ranges library :)<br>
>     auto ctr = [](){};<br>
> <br>
>     // TUa.cc<br>
>     #include "header.h"<br>
> <br>
>     // these instantiations are _Z3barIN3ctrMUlvE_EEiT_ due to the<br>
>     // above-mentioned attachment<br>
>     int maker1 () { return bar (ctr); }<br>
> <br>
>     // TUb.cc<br>
>     #include "header.h"<br>
>     int maker2 () { return bar (ctr); }<br>
> <br>
>     Those maker[12] functions are calling the exact same bar instantiation,<br>
> <br>
> <br>
> I don't think that's right -- this program contains an ODR violation due <br>
> to redefinition of 'ctr' (with two different types) in TUa and TUb.<br>
<br>
Oh, I forgot to make 'ctr' inline -- that would remove that ODR, right? <br>
(Or am I just confusing trauma from header-units :) )<br></blockquote><div><br></div><div>Yes, making 'ctr' inline would address that. It also causes Clang to mangle the lambda following the ABI rule. Er... except, with that change:</div><div><br></div><div>GCC mangles i as _ZZ3barIN3ctrMUlvE_EEiT_E1i</div><div>Clang mangles i as _ZZ3barI3ctrMUlvE_EiT_E1i</div><div><br></div><div>The ABI document doesn't say how to mangle this case at all; the relevant mangling rule seems (surprisingly) to be <data-member-prefix>, but that can only appear after a <prefix>, which we don't have here. So it's unclear whether this should be mangled as <data-member-prefix> <unqualified-name> or as N <data-member-prefix> <unqualified-name> E.</div><div><br></div><div>I suppose we have to pick the latter (and that's what demanglers expect) because ...I3ctrM... could also be ...<ctr, (some pointer-to-member type)... -- so it looks like that's a Clang ABI bug and a bug in the ABI document :) I've added a description of the latter to <a href="https://github.com/itanium-cxx-abi/cxx-abi/issues/94">https://github.com/itanium-cxx-abi/cxx-abi/issues/94</a>.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
> There is no ABI requirement to use a specific mangling for entities that <br>
> are not externally visible, and Clang takes advantage of this to avoid <br>
> strictly numbering lambdas that are only visible in a single TU. Though <br>
> it's unfortunate that we put a '$' in the name in such cases; that seems <br>
> to confuse some demanglers that incorrectly think that identifiers can <br>
> contain only [A-Za-z0-9_], and results in a demangling that doesn't <br>
> mention that we are inside a lambda.<br>
<br>
<br>
<br>
> <br>
>     so should see consistent numbering from the static variable.<br>
> <br>
>     hope that helps.<br>
>      ><br>
>      ><br>
>      >      >> However there are use-cases where I find it very<br>
>     inconvenient when<br>
>      >      >> they generate different names. For example, if we are to<br>
>     compare the<br>
>      >      >> performance difference of the same software compiled<br>
>     under Clang and<br>
>      >      >> GCC, the perf stack traces will look very different<br>
>     because of the<br>
>      >      >> naming differences, making it hard to compare.<br>
>      >      >> Is there any particular reason that Clang uses a<br>
>     different naming<br>
>      >      >> convention for lambdas, and would there be push-backs if<br>
>     we were to<br>
>      >      >> make it consistent with GCC?<br>
>      ><br>
>      >     It would be good to have clang match the ABI.  I am not sure<br>
>     how much<br>
>      >     pain it would be for users to switch though -- perhaps having two<br>
>      >     manglings and therefore two distinct instances in the same<br>
>     executable.<br>
>      >     Other than code bloat most would not notice, unless someone put a<br>
>      >     static<br>
>      >     var into their lambda operator.<br>
>      ><br>
>      >      >> Thanks.<br>
>      >      >><br>
>      >      >> --<br>
>      >      >> Xun<br>
>      >      >> _______________________________________________<br>
>      >      >> LLVM Developers mailing list<br>
>      >      >> <a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a> <mailto:<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>><br>
>     <mailto:<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a> <mailto:<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>>><br>
>      >      >> <a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a><br>
>     <<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a>><br>
>      >     <<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a><br>
>     <<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a>>><br>
>      >      > _______________________________________________<br>
>      >      > cfe-dev mailing list<br>
>      >      > <a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a> <mailto:<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>><br>
>     <mailto:<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a> <mailto:<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>>><br>
>      >      > <a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a><br>
>     <<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a>><br>
>      >     <<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a><br>
>     <<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a>>><br>
>      >      ><br>
>      ><br>
>      ><br>
>      >     --<br>
>      >     Nathan Sidwell<br>
>      >     _______________________________________________<br>
>      >     cfe-dev mailing list<br>
>      > <a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a> <mailto:<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>><br>
>     <mailto:<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a> <mailto:<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>>><br>
>      > <a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a><br>
>     <<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a>><br>
>      >     <<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a><br>
>     <<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a>>><br>
>      ><br>
>      ><br>
>      > _______________________________________________<br>
>      > cfe-dev mailing list<br>
>      > <a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a> <mailto:<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>><br>
>      > <a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a><br>
>     <<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a>><br>
>      ><br>
> <br>
> <br>
>     -- <br>
>     Nathan Sidwell<br>
>     _______________________________________________<br>
>     cfe-dev mailing list<br>
>     <a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a> <mailto:<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>><br>
>     <a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a><br>
>     <<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a>><br>
> <br>
<br>
<br>
-- <br>
Nathan Sidwell<br>
</blockquote></div></div>