<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Oct 19, 2016, at 6:53 PM, Richard Smith <<a href="mailto:richard@metafoo.co.uk" class="">richard@metafoo.co.uk</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><div class="gmail_extra"><div class="gmail_quote">On Tue, Oct 18, 2016 at 8:37 AM, Duncan P. N. Exon Smith via cfe-dev<span class="Apple-converted-space"> </span><span dir="ltr" class=""><<a href="mailto:cfe-dev@lists.llvm.org" target="_blank" class="">cfe-dev@lists.llvm.org</a>></span><span class="Apple-converted-space"> </span>wrote:<br class=""><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;"><span class=""><br class="">> On 2016-Oct-13, at 22:46, Mehdi Amini via cfe-dev <<a href="mailto:cfe-dev@lists.llvm.org" class="">cfe-dev@lists.llvm.org</a>> wrote:<br class="">><br class="">> Hi,<br class="">><br class="">> This fairly simple (and valid) code does not link (on MacOS):<br class="">><br class="">><br class="">> #include <iostream><br class="">> #include <string><br class="">> namespace {<br class="">> struct VA {<br class="">> };<br class="">> struct A : virtual public VA {<br class="">> A() {<br class="">> static bool b = false;<br class="">> std::string str;<br class="">> }<br class="">> };<br class="">> }<br class="">> int main(int argc, char* argv[]) {<br class="">> A::A a;<br class="">> }<br class="">><br class="">><br class="">><br class="">> The issue is that clang emits two constructors (the complete one and the base one) for struct A because it has a virtual base class.<br class="">><br class="">> Because struct A is declared in an anonymous namespace, these constructors are internal linkage. Only one of them is actually called, the other is unreachable.<br class="">><br class="">> The “always-inliner” does not visit unreachable internal function. However this constructor is calling into a function from libc++ that are marked “available_externally” and “always inline”: the basic_string constructor.<br class="">><br class="">> The problem is that the linkage “available_externally" is a “lie”: there is an external template instantiation in the header, but it is marked “visibility hidden”. So the function cannot be linked to in the libc++ dylib. (I think it’d work with a static libc++).<br class="">><br class="">> I see multiple ways to address such cases, possibly many of them can be implemented:<br class="">><br class="">> - Don’t emit unreferenced internal_linkage function. (We should try to do this anyway right?)<br class=""><br class=""></span>This makes sense to me. It seems to me like a bug that it's emitted.</blockquote><div class=""><br class=""></div><div class="">Regardless, resolving it does not fix the problem here. For instance, the same issue would arise under -femit-all-decls, or if uses exist at the AST level but are optimized away after IR generation.</div></div></div></div></div></blockquote><div><br class=""></div><div>If uses are optimized away after IR generation, this is not a problem from an LLVM point of view: clang didn’t emit an unreachable internal function in the first place, LLVM will track that the uses were removed and delete the `newly unreachable` internal function.</div><div><br class=""></div><div>Your point stands for -femit-all-decls though.</div><div><br class=""></div><div>— </div><div>Mehdi</div><div><br class=""></div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><div class="gmail_extra"><div class="gmail_quote"><div class=""><br class=""></div><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;"><span class="">> - Have the CGSCC run on the unreachable part of the call-graph.<br class=""><br class=""></span>This seems to pessimize the normal case.</blockquote><div class=""><br class=""></div><div class="">Nonetheless, it's necessary if we want to provide the guarantee that the always_inline attribute is supposed to provide. (It's not a hint; per the GCC documentation it is an error if a function is annotated always_inline and is not inlined.)</div><div class=""><br class=""></div><div class="">If we don't want to provide that guarantee, so be it, but then libc++'s use of this attribute is simply wrong, since it's relying on that guarantee.</div><div class=""><br class=""></div><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;"><span class="">> - Run global-DCE at O0 (might be a good idea anyway if it speeds-up the build)<br class=""><br class=""></span>Would we be surprised by anything it deletes? If it's only going to delete unreferenced static globals, it seems (1) harmless and (2) unnecessary unless there are frontend bugs. But maybe it's<br class=""><span class=""><br class="">> - We should have the “available_externally” compatible with “hidden visibility”. Maybe we need a way to have to mark some method excluded from one `external template` instantiation so that it would be ODR.<br class=""><br class=""></span>This seems useful. I think individual functions should be able to opt-out of a class-wide `extern template` instantiation.<br class=""><span class=""><br class="">> - We could make the basic_string constructor and other method in the same situation internal linkage instead.<br class=""><br class=""></span>Could pointer equality fail on the function pointers of basic_string::basic_string?<br class=""><div class="HOEnZb"><div class="h5"><br class="">><br class="">><br class="">> Thoughts?<br class="">><br class="">> —<br class="">> Mehdi<br class="">> ______________________________<wbr class="">_________________<br class="">> cfe-dev mailing list<br class="">><span class="Apple-converted-space"> </span><a href="mailto:cfe-dev@lists.llvm.org" class="">cfe-dev@lists.llvm.org</a><br class="">><span class="Apple-converted-space"> </span><a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank" class="">http://lists.llvm.org/cgi-bin/<wbr class="">mailman/listinfo/cfe-dev</a><br class=""><br class="">______________________________<wbr class="">_________________<br class="">cfe-dev mailing list<br class=""><a href="mailto:cfe-dev@lists.llvm.org" class="">cfe-dev@lists.llvm.org</a><br class=""><a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank" class="">http://lists.llvm.org/cgi-bin/<wbr class="">mailman/listinfo/cfe-dev</a></div></div></blockquote></div></div></div></div></blockquote></div><br class=""></body></html>