[asan] added tests for asan-initialization-order, patch by Reid Watson

git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@163207 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/asan/lit_tests/Helpers/blacklist-extra.cc b/lib/asan/lit_tests/Helpers/blacklist-extra.cc
new file mode 100644
index 0000000..627115c
--- /dev/null
+++ b/lib/asan/lit_tests/Helpers/blacklist-extra.cc
@@ -0,0 +1,5 @@
+// This function is broken, but this file is blacklisted
+int externalBrokenFunction(int argc) {
+  char x[10] = {0};
+  return x[argc * 10];  // BOOM
+}
diff --git a/lib/asan/lit_tests/Helpers/initialization-bug-extra.cc b/lib/asan/lit_tests/Helpers/initialization-bug-extra.cc
new file mode 100644
index 0000000..3c4cb41
--- /dev/null
+++ b/lib/asan/lit_tests/Helpers/initialization-bug-extra.cc
@@ -0,0 +1,5 @@
+// This file simply declares a dynamically initialized var by the name of 'y'.
+int initY() {
+  return 5;
+}
+int y = initY();
diff --git a/lib/asan/lit_tests/Helpers/initialization-nobug-extra.cc b/lib/asan/lit_tests/Helpers/initialization-nobug-extra.cc
new file mode 100644
index 0000000..490b333
--- /dev/null
+++ b/lib/asan/lit_tests/Helpers/initialization-nobug-extra.cc
@@ -0,0 +1,9 @@
+// Linker initialized:
+int getAB();
+static int ab = getAB();
+// Function local statics:
+int countCalls();
+static int one = countCalls();
+// Constexpr:
+int getCoolestInteger();
+static int coolest_integer = getCoolestInteger();
diff --git a/lib/asan/lit_tests/Helpers/lit.local.cfg b/lib/asan/lit_tests/Helpers/lit.local.cfg
new file mode 100644
index 0000000..2fc4d99
--- /dev/null
+++ b/lib/asan/lit_tests/Helpers/lit.local.cfg
@@ -0,0 +1,3 @@
+# Sources in this directory are helper files for tests which test functionality
+# involving multiple translation units.
+config.suffixes = []
diff --git a/lib/asan/lit_tests/blacklist.cc b/lib/asan/lit_tests/blacklist.cc
new file mode 100644
index 0000000..ef70956
--- /dev/null
+++ b/lib/asan/lit_tests/blacklist.cc
@@ -0,0 +1,44 @@
+// Test the blacklist functionality of ASan
+
+// RUN: echo "fun:*brokenFunction*" > %tmp
+// RUN: echo "global:*badGlobal*" >> %tmp
+// RUN: echo "src:*blacklist-extra.cc" >> %tmp
+// RUN: %clangxx_asan -mllvm -asan-blacklist=%tmp -m64 -O0 %s -o %t \
+// RUN: %p/Helpers/blacklist-extra.cc && %t 2>&1
+// RUN: %clangxx_asan -mllvm -asan-blacklist=%tmp -m64 -O1 %s -o %t \
+// RUN: %p/Helpers/blacklist-extra.cc && %t 2>&1
+// RUN: %clangxx_asan -mllvm -asan-blacklist=%tmp -m64 -O2 %s -o %t \
+// RUN: %p/Helpers/blacklist-extra.cc && %t 2>&1
+// RUN: %clangxx_asan -mllvm -asan-blacklist=%tmp -m64 -O3 %s -o %t \
+// RUN: %p/Helpers/blacklist-extra.cc && %t 2>&1
+// RUN: %clangxx_asan -mllvm -asan-blacklist=%tmp -m32 -O0 %s -o %t \
+// RUN: %p/Helpers/blacklist-extra.cc && %t 2>&1
+// RUN: %clangxx_asan -mllvm -asan-blacklist=%tmp -m32 -O1 %s -o %t \
+// RUN: %p/Helpers/blacklist-extra.cc && %t 2>&1
+// RUN: %clangxx_asan -mllvm -asan-blacklist=%tmp -m32 -O2 %s -o %t \
+// RUN: %p/Helpers/blacklist-extra.cc && %t 2>&1
+// RUN: %clangxx_asan -mllvm -asan-blacklist=%tmp -m32 -O3 %s -o %t \
+// RUN: %p/Helpers/blacklist-extra.cc && %t 2>&1
+
+// badGlobal is accessed improperly, but we blacklisted it.
+int badGlobal;
+int readBadGlobal() {
+  return (&badGlobal)[1];
+}
+
+// A function which is broken, but excluded in the blacklist.
+int brokenFunction(int argc) {
+  char x[10] = {0};
+  return x[argc * 10];  // BOOM
+}
+
+// This function is defined in Helpers/blacklist-extra.cc, a source file which
+// is blacklisted by name
+int externalBrokenFunction(int x);
+
+int main(int argc, char **argv) {
+  brokenFunction(argc);
+  int x = readBadGlobal();
+  externalBrokenFunction(argc);
+  return 0;
+}
diff --git a/lib/asan/lit_tests/initialization-bug.cc b/lib/asan/lit_tests/initialization-bug.cc
new file mode 100644
index 0000000..872b8bf
--- /dev/null
+++ b/lib/asan/lit_tests/initialization-bug.cc
@@ -0,0 +1,33 @@
+// Test to make sure basic initialization order errors are caught.
+
+// RUN: %clangxx_asan -m64 -O0 %s %p/Helpers/initialization-bug-extra.cc\
+// RUN:   -mllvm -asan-initialization-order -o %t && %t 2>&1 \
+// RUN:    | %symbolize | FileCheck %s
+// RUN: %clangxx_asan -m32 -O0 %s %p/Helpers/initialization-bug-extra.cc\
+// RUN:   -mllvm -asan-initialization-order -o %t && %t 2>&1 \
+// RUN:     | %symbolize | FileCheck %s
+
+// Do not test with optimization -- the error may be optimized away.
+
+extern int y;
+
+// 'y' is a dynamically initialized global residing in a different TU.  This
+// dynamic initializer will read the value of 'y' before main starts.  The
+// result is undefined behavior, which should be caught by initialization order
+// checking.
+int __attribute__((noinline)) initX() {
+  return y + 1;
+  // CHECK: {{AddressSanitizer initialization-order-fiasco}}
+  // CHECK: {{READ of size .* at 0x.* thread T0}}
+  // CHECK: {{#0 0x.* in .*initX.* .*initialization-bug.cc:19}}
+  // CHECK: {{0x.* is located 0 bytes inside of global variable .*y.*}}
+}
+
+
+// This initializer begins our initialization order problems.
+static int x = initX();
+
+// ASan should have caused an exit before main runs.
+int main() {
+  return -1;
+}
diff --git a/lib/asan/lit_tests/initialization-nobug.cc b/lib/asan/lit_tests/initialization-nobug.cc
new file mode 100644
index 0000000..cd68b13
--- /dev/null
+++ b/lib/asan/lit_tests/initialization-nobug.cc
@@ -0,0 +1,67 @@
+// A collection of various initializers which shouldn't trip up initialization
+// order checking.  If successful, this will just return 0.
+
+// RUN: %clangxx_asan -m64 -O0 %s %p/Helpers/initialization-nobug-extra.cc\
+// RUN:   --std=c++11 -mllvm -asan-initialization-order -o %t && %t 2>&1
+// RUN: %clangxx_asan -m64 -O1 %s %p/Helpers/initialization-nobug-extra.cc\
+// RUN:   --std=c++11 -mllvm -asan-initialization-order -o %t && %t 2>&1
+// RUN: %clangxx_asan -m64 -O2 %s %p/Helpers/initialization-nobug-extra.cc\
+// RUN:   --std=c++11 -mllvm -asan-initialization-order -o %t && %t 2>&1
+// RUN: %clangxx_asan -m64 -O3 %s %p/Helpers/initialization-nobug-extra.cc\
+// RUN:   --std=c++11 -mllvm -asan-initialization-order -o %t && %t 2>&1
+// RUN: %clangxx_asan -m32 -O0 %s %p/Helpers/initialization-nobug-extra.cc\
+// RUN:   --std=c++11 -mllvm -asan-initialization-order -o %t && %t 2>&1
+// RUN: %clangxx_asan -m32 -O0 %s %p/Helpers/initialization-nobug-extra.cc\
+// RUN:   --std=c++11 -mllvm -asan-initialization-order -o %t && %t 2>&1
+// RUN: %clangxx_asan -m32 -O1 %s %p/Helpers/initialization-nobug-extra.cc\
+// RUN:   --std=c++11 -mllvm -asan-initialization-order -o %t && %t 2>&1
+// RUN: %clangxx_asan -m32 -O2 %s %p/Helpers/initialization-nobug-extra.cc\
+// RUN:   --std=c++11 -mllvm -asan-initialization-order -o %t && %t 2>&1
+// RUN: %clangxx_asan -m32 -O3 %s %p/Helpers/initialization-nobug-extra.cc\
+// RUN:   --std=c++11 -mllvm -asan-initialization-order -o %t && %t 2>&1
+
+// Simple access:
+// Make sure that accessing a global in the same TU is safe
+
+bool condition = true;
+int initializeSameTU() {
+  return condition ? 0x2a : 052;
+}
+int sameTU = initializeSameTU();
+
+// Linker initialized:
+// Check that access to linker initialized globals originating from a different
+// TU's initializer is safe.
+
+int A = (1 << 1) + (1 << 3) + (1 << 5), B;
+int getAB() {
+  return A * B;
+}
+
+// Function local statics:
+// Check that access to function local statics originating from a different
+// TU's initializer is safe.
+
+int countCalls() {
+  static int calls;
+  return ++calls;
+}
+
+// Constexpr:
+// We need to check that a global variable initialized with a constexpr
+// constructor can be accessed during dynamic initialization (as a constexpr
+// constructor implies that it was initialized during constant initialization,
+// not dynamic initialization).
+
+class Integer {
+  private:
+  int value;
+
+  public:
+  constexpr Integer(int x = 0) : value(x) {}
+  int getValue() {return value;}
+};
+Integer coolestInteger(42);
+int getCoolestInteger() { return coolestInteger.getValue(); }
+
+int main() { return 0; }
diff --git a/lib/sanitizer_common/scripts/check_lint.sh b/lib/sanitizer_common/scripts/check_lint.sh
index 50f3abe..42fb758 100755
--- a/lib/sanitizer_common/scripts/check_lint.sh
+++ b/lib/sanitizer_common/scripts/check_lint.sh
@@ -54,8 +54,7 @@
 ${CPPLINT} --filter=${ASAN_TEST_LINT_FILTER} ${ASAN_RTL}/tests/*.{cc,h} \
                                              ${ASAN_RTL}/output_tests/*.cc
 ${CPPLINT} --filter=${ASAN_TEST_LINT_FILTER} ${ASAN_RTL}/lit_tests/*.cc \
-                                             ${ASAN_RTL}/lit_tests/Linux/*.cc \
-                                             ${ASAN_RTL}/lit_tests/SharedLibs/*.cc
+                                             ${ASAN_RTL}/lit_tests/*/*.cc \
 
 # TSan
 TSAN_RTL=${COMPILER_RT}/lib/tsan