<div dir="ltr">And this ubsan report<div><a href="http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-fast/builds/5002/steps/check-llvm%20ubsan/logs/stdio">http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-fast/builds/5002/steps/check-llvm%20ubsan/logs/stdio</a><br><div><br></div><div><pre style="font-family:"Courier New",courier,monotype,monospace;font-size:medium"><span class="inbox-inbox-stdout">-- Testing: 20698 tests, 32 threads --
Testing: 0 ..
FAIL: LLVM-Unit :: Support/SupportTests/CrashRecoveryTest.Cleanup (1887 of 20698)
******************** TEST 'LLVM-Unit :: Support/SupportTests/CrashRecoveryTest.Cleanup' FAILED ********************
Note: Google Test filter = CrashRecoveryTest.Cleanup
[==========] Running 1 test from 1 test case.
[----------] Global test environment set-up.
[----------] 1 test from CrashRecoveryTest
[ RUN      ] CrashRecoveryTest.Cleanup
/mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/unittests/Support/CrashRecoveryTest.cpp:24:27: runtime error: store to null pointer of type 'volatile int'
    #0 0x4a8b41 in nullDeref() /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/unittests/Support/CrashRecoveryTest.cpp:24:52
    #1 0x6c4c66 in llvm::CrashRecoveryContext::RunSafely(llvm::function_ref<void ()>) /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/lib/Support/CrashRecoveryContext.cpp:359:3
    #2 0x4a8d81 in CrashRecoveryTest_Cleanup_Test::TestBody() /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/unittests/Support/CrashRecoveryTest.cpp:59:5
    #3 0x7ad659 in testing::Test::Run() /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/utils/unittest/googletest/src/gtest.cc:2474:5
    #4 0x7ae118 in testing::TestInfo::Run() /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/utils/unittest/googletest/src/gtest.cc:2656:11
    #5 0x7ae812 in testing::TestCase::Run() /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/utils/unittest/googletest/src/gtest.cc:2774:28
    #6 0x7b4ce3 in testing::internal::UnitTestImpl::RunAllTests() /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/utils/unittest/googletest/src/gtest.cc:4649:43
    #7 0x7b497b in testing::UnitTest::Run() /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/utils/unittest/googletest/src/gtest.cc:4257:10
    #8 0x7a39b3 in main /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/utils/unittest/UnitTestMain/TestMain.cpp:51:10
    #9 0x7f0b6d09082f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
    #10 0x430c78 in _start (/mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm_build_ubsan/unittests/Support/SupportTests+0x430c78)
</span></pre><br class="inbox-inbox-Apple-interchange-newline"></div></div></div><br><div class="gmail_quote"><div dir="ltr">On Wed, May 17, 2017 at 1:13 PM Vitaly Buka <<a href="mailto:vitalybuka@google.com">vitalybuka@google.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><a href="http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-fast/builds/5002/steps/check-llvm%20asan/logs/stdio" class="cremed">http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-fast/builds/5002/steps/check-llvm%20asan/logs/stdio</a><div><br></div><div><pre style="font-family:"Courier New",courier,monotype,monospace;font-size:medium"><span class="inbox-inbox-stdout">SAN:DEADLYSIGNAL
=================================================================
==24802==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x000000660cef bp 0x7fffa59551f0 sp 0x7fffa59551f0 T0)
==24802==The signal is caused by a WRITE memory access.
==24802==Hint: address points to the zero page.
    #0 0x660cee in nullDeref() /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/unittests/Support/CrashRecoveryTest.cpp:24:52
    #1 0xc7e51b in operator() /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/include/llvm/ADT/STLExtras.h:111:12
    #2 0xc7e51b in llvm::CrashRecoveryContext::RunSafely(llvm::function_ref<void ()>) /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/lib/Support/CrashRecoveryContext.cpp:359
    #3 0x6614a1 in CrashRecoveryTest_Cleanup_Test::TestBody() /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/unittests/Support/CrashRecoveryTest.cpp:59:5
    #4 0xdc9a3e in HandleExceptionsInMethodIfSupported<testing::Test, void> /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/utils/unittest/googletest/src/gtest.cc:2458:12
    #5 0xdc9a3e in testing::Test::Run() /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/utils/unittest/googletest/src/gtest.cc:2474
    #6 0xdce174 in testing::TestInfo::Run() /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/utils/unittest/googletest/src/gtest.cc:2656:11
    #7 0xdcf4a6 in testing::TestCase::Run() /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/utils/unittest/googletest/src/gtest.cc:2774:28
    #8 0xdef336 in testing::internal::UnitTestImpl::RunAllTests() /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/utils/unittest/googletest/src/gtest.cc:4649:43
    #9 0xdee692 in HandleExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool> /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/utils/unittest/googletest/src/gtest.cc:2458:12
    #10 0xdee692 in testing::UnitTest::Run() /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/utils/unittest/googletest/src/gtest.cc:4257
    #11 0xdad59b in RUN_ALL_TESTS /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/utils/unittest/googletest/include/gtest/gtest.h:2233:46
    #12 0xdad59b in main /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/utils/unittest/UnitTestMain/TestMain.cpp:51
    #13 0x7ff81ab8982f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
    #14 0x485d98 in _start (/mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm_build_asan/unittests/Support/SupportTests+0x485d98)
</span></pre><br class="inbox-inbox-Apple-interchange-newline"></div></div><br><div class="gmail_quote"><div dir="ltr">On Wed, May 17, 2017 at 11:29 AM Reid Kleckner via llvm-commits <<a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: rnk<br>
Date: Wed May 17 13:16:17 2017<br>
New Revision: 303279<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=303279&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=303279&view=rev</a><br>
Log:<br>
Re-land r303274: "[CrashRecovery] Use SEH __try instead of VEH when available"<br>
<br>
We have to check gCrashRecoveryEnabled before using __try.<br>
<br>
In other words, SEH works too well and we ended up recovering from<br>
crashes in implicit module builds that we weren't supposed to. Only<br>
libclang is supposed to enable CrashRecoveryContext to allow implicit<br>
module builds to crash.<br>
<br>
Added:<br>
    llvm/trunk/unittests/Support/CrashRecoveryTest.cpp<br>
Modified:<br>
    llvm/trunk/lib/Support/CrashRecoveryContext.cpp<br>
    llvm/trunk/unittests/Support/CMakeLists.txt<br>
<br>
Modified: llvm/trunk/lib/Support/CrashRecoveryContext.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/CrashRecoveryContext.cpp?rev=303279&r1=303278&r2=303279&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/CrashRecoveryContext.cpp?rev=303279&r1=303278&r2=303279&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Support/CrashRecoveryContext.cpp (original)<br>
+++ llvm/trunk/lib/Support/CrashRecoveryContext.cpp Wed May 17 13:16:17 2017<br>
@@ -78,6 +78,9 @@ static bool gCrashRecoveryEnabled = fals<br>
 static ManagedStatic<sys::ThreadLocal<const CrashRecoveryContext>><br>
        tlIsRecoveringFromCrash;<br>
<br>
+static void installExceptionOrSignalHandlers();<br>
+static void uninstallExceptionOrSignalHandlers();<br>
+<br>
 CrashRecoveryContextCleanup::~CrashRecoveryContextCleanup() {}<br>
<br>
 CrashRecoveryContext::~CrashRecoveryContext() {<br>
@@ -113,6 +116,23 @@ CrashRecoveryContext *CrashRecoveryConte<br>
   return CRCI->CRC;<br>
 }<br>
<br>
+void CrashRecoveryContext::Enable() {<br>
+  sys::ScopedLock L(*gCrashRecoveryContextMutex);<br>
+  // FIXME: Shouldn't this be a refcount or something?<br>
+  if (gCrashRecoveryEnabled)<br>
+    return;<br>
+  gCrashRecoveryEnabled = true;<br>
+  installExceptionOrSignalHandlers();<br>
+}<br>
+<br>
+void CrashRecoveryContext::Disable() {<br>
+  sys::ScopedLock L(*gCrashRecoveryContextMutex);<br>
+  if (!gCrashRecoveryEnabled)<br>
+    return;<br>
+  gCrashRecoveryEnabled = false;<br>
+  uninstallExceptionOrSignalHandlers();<br>
+}<br>
+<br>
 void CrashRecoveryContext::registerCleanup(CrashRecoveryContextCleanup *cleanup)<br>
 {<br>
   if (!cleanup)<br>
@@ -140,27 +160,56 @@ CrashRecoveryContext::unregisterCleanup(<br>
   delete cleanup;<br>
 }<br>
<br>
-#ifdef LLVM_ON_WIN32<br>
+#if defined(_MSC_VER)<br>
+// If _MSC_VER is defined, we must have SEH. Use it if it's available. It's way<br>
+// better than VEH. Vectored exception handling catches all exceptions happening<br>
+// on the thread with installed exception handlers, so it can interfere with<br>
+// internal exception handling of other libraries on that thread. SEH works<br>
+// exactly as you would expect normal exception handling to work: it only<br>
+// catches exceptions if they would bubble out from the stack frame with __try /<br>
+// __except.<br>
<br>
-#include "Windows/WindowsSupport.h"<br>
+static void installExceptionOrSignalHandlers() {}<br>
+static void uninstallExceptionOrSignalHandlers() {}<br>
+<br>
+bool CrashRecoveryContext::RunSafely(function_ref<void()> Fn) {<br>
+  if (!gCrashRecoveryEnabled) {<br>
+    Fn();<br>
+    return true;<br>
+  }<br>
+<br>
+  bool Result = true;<br>
+  __try {<br>
+    Fn();<br>
+  } __except (1) { // Catch any exception.<br>
+    Result = false;<br>
+  }<br>
+  return Result;<br>
+}<br>
+<br>
+#else // !_MSC_VER<br>
<br>
-// On Windows, we can make use of vectored exception handling to<br>
-// catch most crashing situations.  Note that this does mean<br>
-// we will be alerted of exceptions *before* structured exception<br>
-// handling has the opportunity to catch it.  But that isn't likely<br>
-// to cause problems because nowhere in the project is SEH being<br>
-// used.<br>
+#if defined(LLVM_ON_WIN32)<br>
+// This is a non-MSVC compiler, probably mingw gcc or clang without<br>
+// -fms-extensions. Use vectored exception handling (VEH).<br>
 //<br>
-// Vectored exception handling is built on top of SEH, and so it<br>
-// works on a per-thread basis.<br>
+// On Windows, we can make use of vectored exception handling to catch most<br>
+// crashing situations.  Note that this does mean we will be alerted of<br>
+// exceptions *before* structured exception handling has the opportunity to<br>
+// catch it. Unfortunately, this causes problems in practice with other code<br>
+// running on threads with LLVM crash recovery contexts, so we would like to<br>
+// eventually move away from VEH.<br>
+//<br>
+// Vectored works on a per-thread basis, which is an advantage over<br>
+// SetUnhandledExceptionFilter. SetUnhandledExceptionFilter also doesn't have<br>
+// any native support for chaining exception handlers, but VEH allows more than<br>
+// one.<br>
 //<br>
 // The vectored exception handler functionality was added in Windows<br>
 // XP, so if support for older versions of Windows is required,<br>
 // it will have to be added.<br>
-//<br>
-// If we want to support as far back as Win2k, we could use the<br>
-// SetUnhandledExceptionFilter API, but there's a risk of that<br>
-// being entirely overwritten (it's not a chain).<br>
+<br>
+#include "Windows/WindowsSupport.h"<br>
<br>
 static LONG CALLBACK ExceptionHandler(PEXCEPTION_POINTERS ExceptionInfo)<br>
 {<br>
@@ -203,14 +252,7 @@ static LONG CALLBACK ExceptionHandler(PE<br>
 // non-NULL, valid VEH handles, or NULL.<br>
 static sys::ThreadLocal<const void> sCurrentExceptionHandle;<br>
<br>
-void CrashRecoveryContext::Enable() {<br>
-  sys::ScopedLock L(*gCrashRecoveryContextMutex);<br>
-<br>
-  if (gCrashRecoveryEnabled)<br>
-    return;<br>
-<br>
-  gCrashRecoveryEnabled = true;<br>
-<br>
+static void installExceptionOrSignalHandlers() {<br>
   // We can set up vectored exception handling now.  We will install our<br>
   // handler as the front of the list, though there's no assurances that<br>
   // it will remain at the front (another call could install itself before<br>
@@ -219,14 +261,7 @@ void CrashRecoveryContext::Enable() {<br>
   sCurrentExceptionHandle.set(handle);<br>
 }<br>
<br>
-void CrashRecoveryContext::Disable() {<br>
-  sys::ScopedLock L(*gCrashRecoveryContextMutex);<br>
-<br>
-  if (!gCrashRecoveryEnabled)<br>
-    return;<br>
-<br>
-  gCrashRecoveryEnabled = false;<br>
-<br>
+static void uninstallExceptionOrSignalHandlers() {<br>
   PVOID currentHandle = const_cast<PVOID>(sCurrentExceptionHandle.get());<br>
   if (currentHandle) {<br>
     // Now we can remove the vectored exception handler from the chain<br>
@@ -237,7 +272,7 @@ void CrashRecoveryContext::Disable() {<br>
   }<br>
 }<br>
<br>
-#else<br>
+#else // !LLVM_ON_WIN32<br>
<br>
 // Generic POSIX implementation.<br>
 //<br>
@@ -289,14 +324,7 @@ static void CrashRecoverySignalHandler(i<br>
     const_cast<CrashRecoveryContextImpl*>(CRCI)->HandleCrash();<br>
 }<br>
<br>
-void CrashRecoveryContext::Enable() {<br>
-  sys::ScopedLock L(*gCrashRecoveryContextMutex);<br>
-<br>
-  if (gCrashRecoveryEnabled)<br>
-    return;<br>
-<br>
-  gCrashRecoveryEnabled = true;<br>
-<br>
+static void installExceptionOrSignalHandlers() {<br>
   // Setup the signal handler.<br>
   struct sigaction Handler;<br>
   Handler.sa_handler = CrashRecoverySignalHandler;<br>
@@ -308,20 +336,13 @@ void CrashRecoveryContext::Enable() {<br>
   }<br>
 }<br>
<br>
-void CrashRecoveryContext::Disable() {<br>
-  sys::ScopedLock L(*gCrashRecoveryContextMutex);<br>
-<br>
-  if (!gCrashRecoveryEnabled)<br>
-    return;<br>
-<br>
-  gCrashRecoveryEnabled = false;<br>
-<br>
+static void uninstallExceptionOrSignalHandlers() {<br>
   // Restore the previous signal handlers.<br>
   for (unsigned i = 0; i != NumSignals; ++i)<br>
     sigaction(Signals[i], &PrevActions[i], nullptr);<br>
 }<br>
<br>
-#endif<br>
+#endif // !LLVM_ON_WIN32<br>
<br>
 bool CrashRecoveryContext::RunSafely(function_ref<void()> Fn) {<br>
   // If crash recovery is disabled, do nothing.<br>
@@ -339,6 +360,8 @@ bool CrashRecoveryContext::RunSafely(fun<br>
   return true;<br>
 }<br>
<br>
+#endif // !_MSC_VER<br>
+<br>
 void CrashRecoveryContext::HandleCrash() {<br>
   CrashRecoveryContextImpl *CRCI = (CrashRecoveryContextImpl *) Impl;<br>
   assert(CRCI && "Crash recovery context never initialized!");<br>
<br>
Modified: llvm/trunk/unittests/Support/CMakeLists.txt<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Support/CMakeLists.txt?rev=303279&r1=303278&r2=303279&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Support/CMakeLists.txt?rev=303279&r1=303278&r2=303279&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/unittests/Support/CMakeLists.txt (original)<br>
+++ llvm/trunk/unittests/Support/CMakeLists.txt Wed May 17 13:16:17 2017<br>
@@ -11,6 +11,7 @@ add_llvm_unittest(SupportTests<br>
   BlockFrequencyTest.cpp<br>
   BranchProbabilityTest.cpp<br>
   CachePruningTest.cpp<br>
+  CrashRecoveryTest.cpp<br>
   Casting.cpp<br>
   Chrono.cpp<br>
   CommandLineTest.cpp<br>
<br>
Added: llvm/trunk/unittests/Support/CrashRecoveryTest.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Support/CrashRecoveryTest.cpp?rev=303279&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Support/CrashRecoveryTest.cpp?rev=303279&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/unittests/Support/CrashRecoveryTest.cpp (added)<br>
+++ llvm/trunk/unittests/Support/CrashRecoveryTest.cpp Wed May 17 13:16:17 2017<br>
@@ -0,0 +1,83 @@<br>
+//===- llvm/unittest/Support/CrashRecoveryTest.cpp ------------------------===//<br>
+//<br>
+//                     The LLVM Compiler Infrastructure<br>
+//<br>
+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+<br>
+#include "llvm/Support/CrashRecoveryContext.h"<br>
+#include "llvm/Support/Compiler.h"<br>
+#include "gtest/gtest.h"<br>
+<br>
+#ifdef LLVM_ON_WIN32<br>
+#define WIN32_LEAN_AND_MEAN<br>
+#define NOGDI<br>
+#include <windows.h><br>
+#endif<br>
+<br>
+using namespace llvm;<br>
+using namespace llvm::sys;<br>
+<br>
+static int GlobalInt = 0;<br>
+static void nullDeref() { *(volatile int *)nullptr = 0; }<br>
+static void incrementGlobal() { ++GlobalInt; }<br>
+static void llvmTrap() { LLVM_BUILTIN_TRAP; }<br>
+<br>
+TEST(CrashRecoveryTest, Basic) {<br>
+  llvm::CrashRecoveryContext::Enable();<br>
+  GlobalInt = 0;<br>
+  EXPECT_TRUE(CrashRecoveryContext().RunSafely(incrementGlobal));<br>
+  EXPECT_EQ(1, GlobalInt);<br>
+  EXPECT_FALSE(CrashRecoveryContext().RunSafely(nullDeref));<br>
+  EXPECT_FALSE(CrashRecoveryContext().RunSafely(llvmTrap));<br>
+}<br>
+<br>
+struct IncrementGlobalCleanup : CrashRecoveryContextCleanup {<br>
+  IncrementGlobalCleanup(CrashRecoveryContext *CRC)<br>
+      : CrashRecoveryContextCleanup(CRC) {}<br>
+  virtual void recoverResources() { ++GlobalInt; }<br>
+};<br>
+<br>
+static void noop() {}<br>
+<br>
+TEST(CrashRecoveryTest, Cleanup) {<br>
+  llvm::CrashRecoveryContext::Enable();<br>
+  GlobalInt = 0;<br>
+  {<br>
+    CrashRecoveryContext CRC;<br>
+    CRC.registerCleanup(new IncrementGlobalCleanup(&CRC));<br>
+    EXPECT_TRUE(CRC.RunSafely(noop));<br>
+  } // run cleanups<br>
+  EXPECT_EQ(1, GlobalInt);<br>
+<br>
+  GlobalInt = 0;<br>
+  {<br>
+    CrashRecoveryContext CRC;<br>
+    CRC.registerCleanup(new IncrementGlobalCleanup(&CRC));<br>
+    EXPECT_FALSE(CRC.RunSafely(nullDeref));<br>
+  } // run cleanups<br>
+  EXPECT_EQ(1, GlobalInt);<br>
+}<br>
+<br>
+#ifdef LLVM_ON_WIN32<br>
+static void raiseIt() {<br>
+  RaiseException(123, EXCEPTION_NONCONTINUABLE, 0, NULL);<br>
+}<br>
+<br>
+TEST(CrashRecoveryTest, RaiseException) {<br>
+  llvm::CrashRecoveryContext::Enable();<br>
+  EXPECT_FALSE(CrashRecoveryContext().RunSafely(raiseIt));<br>
+}<br>
+<br>
+static void outputString() {<br>
+  OutputDebugStringA("output for debugger\n");<br>
+}<br>
+<br>
+TEST(CrashRecoveryTest, CallOutputDebugString) {<br>
+  llvm::CrashRecoveryContext::Enable();<br>
+  EXPECT_TRUE(CrashRecoveryContext().RunSafely(outputString));<br>
+}<br>
+<br>
+#endif<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
</blockquote></div></blockquote></div>