<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 Nov 16, 2016, at 11:40 AM, Reid Kleckner <<a href="mailto:rnk@google.com" class="">rnk@google.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class="">I totally support solving this problem, but please don't use dynamic initialization to do it. :) That's everyone's least favorite feature of libstdc++ iostream.<div class=""><br class=""></div><div class="">At least on Windows, we can solve this with #pragma detect_mismatch. <a href="https://msdn.microsoft.com/en-us/library/ee956429.aspx" class="">https://msdn.microsoft.com/en-us/library/ee956429.aspx</a></div><div class=""><br class=""></div><div class="">On platforms without such a feature, I'd rather mangle NDEBUG into one of the core LLVM initialization routines than suffer the runtime and code size penalty of initializers.</div></div></div></blockquote><div><br class=""></div><div>Why? I know that static initializer aren’t great but don’t we already have hundreds of them? For instance the cl::opt?</div><div><br class=""></div><div>Also, is there an init routine in LLVM that any client has to use? I grepped llvm/include/llvm without much success.</div><div><br class=""></div><div>— </div><div>Mehdi</div><div><br class=""></div><div><br class=""></div><br class=""><blockquote type="cite" class=""><div class=""><div class="gmail_extra"><br class=""><div class="gmail_quote">On Wed, Nov 16, 2016 at 10:48 AM, Mehdi Amini via llvm-dev <span dir="ltr" class=""><<a href="mailto:llvm-dev@lists.llvm.org" target="_blank" class="">llvm-dev@lists.llvm.org</a>></span> wrote:<br class=""><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word" class="">Hi all,<div class=""><br class=""></div><div class="">An issue that come up from time to time and has cost hours for debug for many of us and users of LLVM is that an assert build isn’t ABI compatible with a release build.</div><div class=""><br class=""></div><div class="">The CMake flags that controls this behavior is LLVM_ABI_BREAKING_CHECKS (</div><div class=""><br class=""></div><div class=""><dt style="font-family:'Lucida Grande','Lucida Sans Unicode',Geneva,Verdana,sans-serif;font-size:14px" class=""><strong class="">LLVM_ABI_BREAKING_CHECKS</strong>:<wbr class="">STRING</dt><dd style="margin-top:3px;margin-bottom:10px;margin-left:30px;font-family:'Lucida Grande','Lucida Sans Unicode',Geneva,Verdana,sans-serif;font-size:14px" class="">Used to decide if LLVM should be built with ABI breaking checks or not. Allowed values are <cite style="font-family:Consolas,'Deja Vu Sans Mono','Bitstream Vera Sans Mono',monospace;font-size:0.95em" class="">WITH_ASSERTS</cite> (default), <cite style="font-family:Consolas,'Deja Vu Sans Mono','Bitstream Vera Sans Mono',monospace;font-size:0.95em" class="">FO<wbr class="">RCE_ON</cite> and <cite style="font-family:Consolas,'Deja Vu Sans Mono','Bitstream Vera Sans Mono',monospace;font-size:0.95em" class="">FORCE_OFF</cite>.  <cite style="font-family:Consolas,'Deja Vu Sans Mono','Bitstream Vera Sans Mono',monospace;font-size:0.95em" class="">WITH_<wbr class="">ASSERTS</cite> turns on ABI breaking checks in an assertion enabled build.  <cite style="font-family:Consolas,'Deja Vu Sans Mono','Bitstream Vera Sans Mono',monospace;font-size:0.95em" class="">FORCE_ON</cite> (<cite style="font-family:Consolas,'Deja Vu Sans Mono','Bitstream Vera Sans Mono',monospace;font-size:0.95em" class="">FORCE_OFF</cite>) turns them on (off) irrespective of whether normal (<cite style="font-family:Consolas,'Deja Vu Sans Mono','Bitstream Vera Sans Mono',monospace;font-size:0.95em" class="">NDEBUG</cite>-based) assertions are enabled or not. A version of LLVM built with ABI breaking checks is not ABI compatible with a version built without it.</dd></div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">I propose to add a runtime check to detect when we have incorrectly setup build.</div><div class=""><br class=""></div><div class="">The idea is that every translation unit that includes such header will get a weak definition of a symbol with an initializer calling the runtime check. The symbol name would be different if the ABI break is enabled or not.</div><div class=""><br class=""></div><div class="">The runtime check maintains two boolean to track if it there is in the image at least a translation unit for each value of this flag. If both flags are set the process is aborted.</div><div class=""><br class=""></div><div class="">The cost is *one* static initializer per DSO (or per image I believe).</div><div class=""><br class=""></div><div class="">A straw-man patch (likely not windows compatible because of weak) is:</div><div class=""><br class=""></div><div class=""><div class="">diff --git a/llvm/include/llvm/Config/<wbr class="">llvm-config.h.cmake b/llvm/include/llvm/Config/<wbr class="">llvm-config.h.cmake</div><div class="">index 4121e865ea00..4274c942d3b6 100644</div><div class="">--- a/llvm/include/llvm/Config/<wbr class="">llvm-config.h.cmake</div><div class="">+++ b/llvm/include/llvm/Config/<wbr class="">llvm-config.h.cmake</div><div class="">@@ -80,4 +80,18 @@</div><div class=""> /* LLVM version string */</div><div class=""> #define LLVM_VERSION_STRING "${PACKAGE_VERSION}"</div><div class=""> </div><div class="">+</div><div class="">+#ifdef __cplusplus</div><div class="">+namespace llvm {</div><div class="">+bool setABIBreakingChecks(bool Enabled);</div><div class="">+__attribute__((weak)) </div><div class="">+#if LLVM_ENABLE_ABI_BREAKING_<wbr class="">CHECKS</div><div class="">+bool</div><div class="">+ABICheckEnabled = setABIBreakingChecks(true);</div><div class="">+#else</div><div class="">+bool ABICheckDisabled = setABIBreakingChecks(true);</div><div class="">+#endif</div><div class="">+}</div><div class="">+#endif</div><div class="">+</div><div class=""> #endif</div><div class="">diff --git a/llvm/lib/Support/Error.cpp b/llvm/lib/Support/Error.cpp</div><div class="">index 7436a1fd38ee..151fcdcbfb27 100644</div><div class="">--- a/llvm/lib/Support/Error.cpp</div><div class="">+++ b/llvm/lib/Support/Error.cpp</div><div class="">@@ -112,3 +112,17 @@ void report_fatal_error(Error Err, bool GenCrashDiag) {</div><div class=""> }</div><div class=""> </div><div class=""> }</div><div class="">+</div><div class="">+</div><div class="">+bool llvm::setABIBreakingChecks(<wbr class="">bool Enabled) {</div><div class="">+  static char abi_breaking_checks_enabled = 0;</div><div class="">+  static char abi_breaking_checks_disabled = 0;</div><div class="">+  if (Enabled)</div><div class="">+    abi_breaking_checks_enabled = 1;</div><div class="">+  else</div><div class="">+    abi_breaking_checks_disabled = 1;</div><div class="">+  if (abi_breaking_checks_enabled && abi_breaking_checks_disabled)</div><div class="">+    report_fatal_error("Error initializing LLVM: mixing translation units built"</div><div class="">+                       "with and without LLVM_ABI_BREAKING_CHECKS");</div><div class="">+  return true;</div><div class="">+}</div></div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">— </div><span class="HOEnZb"><font color="#888888" class=""><div class="">Mehdi</div><div class=""><br class=""></div></font></span></div><br class="">______________________________<wbr class="">_________________<br class="">
LLVM Developers mailing list<br class="">
<a href="mailto:llvm-dev@lists.llvm.org" class="">llvm-dev@lists.llvm.org</a><br class="">
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" rel="noreferrer" target="_blank" class="">http://lists.llvm.org/cgi-bin/<wbr class="">mailman/listinfo/llvm-dev</a><br class="">
<br class=""></blockquote></div><br class=""></div>
</div></blockquote></div><br class=""></body></html>