Make sys::ThreadLocal<> zero-initialized on non-thread builds (PR18205)
authorHans Wennborg <hans@hanshq.net>
Thu, 19 Dec 2013 20:32:44 +0000 (20:32 +0000)
committerHans Wennborg <hans@hanshq.net>
Thu, 19 Dec 2013 20:32:44 +0000 (20:32 +0000)
According to the docs, ThreadLocal<>::get() should return NULL
if no object has been set. This patch makes that the case also for non-thread
builds and adds a very basic unit test to check it.

(This was causing PR18205 because PrettyStackTraceHead didn't get zero-
initialized and we'd crash trying to read past the end of that list. We didn't
notice this so much on Linux since we'd crash after printing all the entries,
but on Mac we print into a SmallString, and would crash before printing that.)

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@197718 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Support/ThreadLocal.cpp
lib/Support/Unix/ThreadLocal.inc
unittests/Support/CMakeLists.txt
unittests/Support/ThreadLocalTest.cpp [new file with mode: 0644]

index 0587aaec7e68fc2c9ca6dacef2095610dac2c2c1..868b6ea566a901ff14503095b00396f9efbb722a 100644 (file)
@@ -23,7 +23,7 @@
 // Define all methods as no-ops if threading is explicitly disabled
 namespace llvm {
 using namespace sys;
-ThreadLocalImpl::ThreadLocalImpl() { }
+ThreadLocalImpl::ThreadLocalImpl() : data() { }
 ThreadLocalImpl::~ThreadLocalImpl() { }
 void ThreadLocalImpl::setInstance(const void* d) {
   typedef int SIZE_TOO_BIG[sizeof(d) <= sizeof(data) ? 1 : -1];
index 2b4c9017cd915befbe1b6d4d672dd01628cf4ad3..f14d0fa3d522e3b592525968f73bb12b7f1e66ee 100644 (file)
@@ -18,7 +18,7 @@
 
 namespace llvm {
 using namespace sys;
-ThreadLocalImpl::ThreadLocalImpl() { }
+ThreadLocalImpl::ThreadLocalImpl() : data() { }
 ThreadLocalImpl::~ThreadLocalImpl() { }
 void ThreadLocalImpl::setInstance(const void* d) { data = const_cast<void*>(d);}
 const void* ThreadLocalImpl::getInstance() { return data; }
index c2753629cb9734fe213afcfea98d9ae2dee29a14..0abc2ffe1d9c8f4aacc807e8ee8ba5ff4832d0dc 100644 (file)
@@ -30,6 +30,7 @@ add_llvm_unittest(SupportTests
   RegexTest.cpp
   SourceMgrTest.cpp
   SwapByteOrderTest.cpp
+  ThreadLocalTest.cpp
   TimeValueTest.cpp
   UnicodeTest.cpp
   ValueHandleTest.cpp
diff --git a/unittests/Support/ThreadLocalTest.cpp b/unittests/Support/ThreadLocalTest.cpp
new file mode 100644 (file)
index 0000000..dd4d706
--- /dev/null
@@ -0,0 +1,38 @@
+//===- llvm/unittest/Support/ThreadLocalTest.cpp - Therad Local tests   ---===//
+//
+//                    The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/ThreadLocal.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+using namespace sys;
+
+namespace {
+
+class ThreadLocalTest : public ::testing::Test {
+};
+
+struct S {
+  int i;
+};
+
+TEST_F(ThreadLocalTest, Basics) {
+  ThreadLocal<const S> x;
+
+  EXPECT_EQ(0, x.get());
+
+  S s;
+  x.set(&s);
+  EXPECT_EQ(&s, x.get());
+
+  x.erase();
+  EXPECT_EQ(0, x.get());
+}
+
+}