Index: gcc/testsuite/gcc.dg/asan/asan.exp
===================================================================
--- gcc/testsuite/gcc.dg/asan/asan.exp	(revision 193881)
+++ gcc/testsuite/gcc.dg/asan/asan.exp	(working copy)
@@ -16,8 +16,6 @@
 # along with GCC; see the file COPYING3.  If not see
 # <http://www.gnu.org/licenses/>.
 
-# GCC testsuite that uses the `dg.exp' driver.
-
 # Load support procs.
 load_lib gcc-dg.exp
 load_lib asan-dg.exp
@@ -30,8 +28,89 @@ if ![check_effective_target_faddress_san
 dg-init
 asan_init
 
+set default_asan_torture_options [list { -O0 -m32 } { -O1 -m32 } { -O2 -m32 } { -O3 -m32 } \
+                                  { -O0 -m64 } { -O1 -m64 } { -O2 -m64 } { -O3 -m64 }]
+
+if { [info procs target_compile] != [list] \
+      && [info procs saved_asan_target_compile] == [list] } {
+  rename target_compile saved_asan_target_compile
+
+  proc target_compile { source dest type options } {
+    global srcdir subdir
+
+    if { [string match "*blacklist-1.c" $source] } {
+      set blacklist_options $options
+      set blist_tmp [glob $srcdir/c-c++-common/asan/Helpers/blacklist-1.tmp]
+      lappend blacklist_options "additional_flags=-asan-blacklist=$blist_tmp"
+      set result [eval [list saved_asan_target_compile $source $dest $type $blacklist_options]]
+      return $result
+    } elseif { [string match "*interface-symbols-1.c" $source] } {
+      set result [eval [list saved_asan_target_compile \
+                        $source "interface-symbols-1.exe" \
+                        "executable" $options]]
+      if { [string match "" $result] } {
+        set exefile [glob interface-symbols-1.exe]
+        set asan_interface_h [glob $srcdir/../../libsanitizer/include/sanitizer/asan_interface.h]
+        set script [glob $srcdir/c-c++-common/asan/Helpers/interface_symbols.sh]
+        set diff_result [exec sh $script $exefile $asan_interface_h]
+        if { ![string match "" $diff_result] } {
+          fail "$source -- diff result not empty: $diff_result"
+        }
+      }
+    } elseif { [string match "*initialization-bug-any-order-1.c" $source] } {
+      set auxfile [glob $srcdir/c-c++-common/asan/Helpers/initialization-bug-extra-1.c]
+      global subtest
+      if { [string match "subtest1" $subtest] } {
+        set source "$source $auxfile"
+      } else {
+        set source "$auxfile $source"
+      }
+      set result [eval [list saved_asan_target_compile $source $dest $type $options]]
+    } else {
+      set result [eval [list saved_asan_target_compile $source $dest $type $options]]
+    }
+    return $result
+  }
+}
+
 # Main loop.
-gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c $srcdir/c-c++-common/asan/*.c]] ""
+foreach srcfile [lsort [glob -nocomplain \
+                        $srcdir/$subdir/*.c \
+                        $srcdir/c-c++-common/asan/*.c \
+                        $srcdir/c-c++-common/asan/linux/*.c]] {
+  set asan_torture_options $default_asan_torture_options
+  if { [string match "*force-inline-opt0-1.c" $srcfile] } { 
+    set asan_torture_options [list { -O0 -m64 } { -O1 -m64 }]
+  } elseif { [string match "*initialization-bug-1.c" $srcfile] } {
+    set asan_torture_options [list { -O0 -m32 } { -O0 -m64 }]
+  } elseif { [string match "*interface-symbols-1.c" $srcfile] } {
+    set asan_torture_options [list { -O2 }]
+  } elseif { [string match "*sleep-before-dying-1.c" $srcfile] } {
+    setenv ASAN_OPTIONS "sleep_before_dying=1"
+    set asan_torture_options [list { -O2 }]
+  } elseif { [string match "*strip-path-prefix-1.c" $srcfile] } {
+    setenv ASAN_OPTIONS "strip_path_prefix='/'"
+    set asan_torture_options [list { -O2 }]
+  } elseif { [string match "*initialization-bug-any-order-1.c" $srcfile] } {
+    set asan_torture_options [list { -O0 }]
+    set-torture-options $asan_torture_options
+    global subtest
+    set subtest "subtest1"
+    gcc-dg-runtest $srcfile ""
+    set subtest "subtest2"
+  } elseif { [string match "*rlimit-mmap-test-1.c" $srcfile] } {
+    set asan_torture_options [list { }]
+    set-torture-options $asan_torture_options
+  }
+
+  set-torture-options $asan_torture_options
+  gcc-dg-runtest $srcfile ""
+
+  if { [string match "*sleep-before-dying-1.c" $srcfile]
+       || [string match "*strip-path-prefix-1.c" $srcfile] } {
+    unsetenv ASAN_OPTIONS
+  }
+}
 
 # All done.
 asan_finish
Index: gcc/testsuite/g++.dg/asan/Helpers/initialization-blacklist-1.tmp
===================================================================
--- gcc/testsuite/g++.dg/asan/Helpers/initialization-blacklist-1.tmp	(revision 0)
+++ gcc/testsuite/g++.dg/asan/Helpers/initialization-blacklist-1.tmp	(revision 0)
@@ -0,0 +1,2 @@
+global-init:*badGlobal*
+global-init-type:*badNamespace::BadClass*
Index: gcc/testsuite/g++.dg/asan/Helpers/initialization-blacklist-extra-1.C
===================================================================
--- gcc/testsuite/g++.dg/asan/Helpers/initialization-blacklist-extra-1.C	(revision 0)
+++ gcc/testsuite/g++.dg/asan/Helpers/initialization-blacklist-extra-1.C	(revision 0)
@@ -0,0 +1,15 @@
+int zero_init() { return 0; }
+int badGlobal = zero_init();
+int readBadGlobal() { return badGlobal; }
+
+namespace badNamespace {
+class BadClass {
+ public:
+  BadClass() { value = 0; }
+  int value;
+};
+// Global object with non-trivial constructor.
+BadClass bad_object;
+}  // namespace badNamespace
+
+int accessBadObject() { return badNamespace::bad_object.value; }
Index: gcc/testsuite/g++.dg/asan/deep-thread-stack-1.C
===================================================================
--- gcc/testsuite/g++.dg/asan/deep-thread-stack-1.C	(revision 0)
+++ gcc/testsuite/g++.dg/asan/deep-thread-stack-1.C	(revision 0)
@@ -0,0 +1,55 @@
+/* { dg-do run } */
+/* { dg-shouldfail "asan" } */
+
+#include <pthread.h>
+
+int *x;
+
+void *AllocThread(void *arg) {
+  x = new int;
+  *x = 42;
+  return NULL;
+}
+
+void *FreeThread(void *arg) {
+  delete x;
+  return NULL;
+}
+
+void *AccessThread(void *arg) {
+  *x = 43;  // BOOM
+  return NULL;
+}
+
+typedef void* (*callback_type)(void* arg);
+
+void *RunnerThread(void *function) {
+  pthread_t thread;
+  pthread_create(&thread, NULL, (callback_type)function, NULL);
+  pthread_join(thread, NULL);
+  return NULL;
+}
+
+void RunThread(callback_type function) {
+  pthread_t runner;
+  pthread_create(&runner, NULL, RunnerThread, (void*)function);
+  pthread_join(runner, NULL);
+}
+
+int main(int argc, char *argv[]) {
+  RunThread(AllocThread);
+  RunThread(FreeThread);
+  RunThread(AccessThread);
+  return (x != 0);
+}
+
+/* { dg-output "ERROR: AddressSanitizer: heap-use-after-free.*(\n|\r\n|\r)" } */
+/* { dg-output "WRITE of size 4 at 0x\[0-9a-f\]+ thread T(\[0-9\]+).*(\n|\r\n|\r)" } */
+/* { dg-output "freed by thread T(\[0-9\]+) here:.*(\n|\r\n|\r)" } */
+/* { dg-output "previously allocated by thread T(\[0-9\]+) here:.*(\n|\r\n|\r)" } */
+/* { dg-output "Thread T\\2 created by T(\[0-9\]+) here:.*(\n|\r\n|\r)" } */
+/* { dg-output "Thread T\\8 created by T0 here:.*(\n|\r\n|\r)" } */
+/* { dg-output "Thread T\\4 created by T(\[0-9\]+) here:.*(\n|\r\n|\r)" } */
+/* { dg-output "Thread T\\11 created by T0 here:.*(\n|\r\n|\r)" } */
+/* { dg-output "Thread T\\6 created by T(\[0-9\]+) here:.*(\n|\r\n|\r)" } */
+/* { dg-output "Thread T\\14 created by T0 here:" } */
Index: gcc/testsuite/g++.dg/asan/shared-lib-test-1.C
===================================================================
--- gcc/testsuite/g++.dg/asan/shared-lib-test-1.C	(revision 0)
+++ gcc/testsuite/g++.dg/asan/shared-lib-test-1.C	(revision 0)
@@ -0,0 +1,33 @@
+/* { dg-do run } */
+/* { dg-shouldfail "asan" } */
+
+#include <dlfcn.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <string>
+
+using std::string;
+
+typedef void (fun_t)(int x);
+
+int main(int argc, char *argv[]) {
+  string path = string(argv[0]) + "-so.so";
+  printf("opening %s ... \n", path.c_str());
+  void *lib = dlopen(path.c_str(), RTLD_NOW);
+  if (!lib) {
+    printf("error in dlopen(): %s\n", dlerror());
+    return 1;
+  }
+  fun_t *inc = (fun_t*)dlsym(lib, "inc");
+  if (!inc) return 1;
+  printf("ok\n");
+  inc(1);
+  inc(-1);  // BOOM
+  return 0;
+}
+
+/* { dg-output "ERROR: AddressSanitizer global-buffer-overflow\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "READ of size 4 at 0x\[0-9a-f\]+ thread T0\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "    #0 0x\[0-9a-f\]+\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "    #1 0x\[0-9a-f\]+ (in _*main \[^\n\r]*(shared-lib-test-1.C:26|\[?\]\[?\]:0)|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */
Index: gcc/testsuite/g++.dg/asan/deep-stack-uaf-1.C
===================================================================
--- gcc/testsuite/g++.dg/asan/deep-stack-uaf-1.C	(revision 0)
+++ gcc/testsuite/g++.dg/asan/deep-stack-uaf-1.C	(revision 0)
@@ -0,0 +1,32 @@
+// Check that we can store lots of stack frames if asked to.
+
+/* { dg-do run } */
+/* { dg-shouldfail "asan" } */
+#include <stdlib.h>
+#include <stdio.h>
+
+template <int depth>
+struct DeepFree {
+  static void free(char *x) {
+    DeepFree<depth - 1>::free(x);
+  }
+};
+
+template<>
+struct DeepFree<0> {
+  static void free(char *x) {
+    ::free(x);
+  }
+};
+
+int main() {
+  char *x = new char[10];
+  // deep_free(x);
+  DeepFree<200>::free(x);
+  return x[5];
+}
+
+/* { dg-output "ERROR: AddressSanitizer heap-use-after-free on address.*(\n|\r\n|\r)" } */
+/* { dg-output "    #37 0x\[0-9a-f\]+ (in \[^\n\r]*DeepFree\[^\n\r]*36|\[(\]).*(\n|\r\n|\r)" } */
+/* { dg-output "    #99 0x\[0-9a-f\]+ (in \[^\n\r]*DeepFree\[^\n\r]*98|\[(\]).*(\n|\r\n|\r)" } */
+/* { dg-output "    #116 0x\[0-9a-f\]+ (in \[^\n\r]*DeepFree\[^\n\r]*115|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */
Index: gcc/testsuite/g++.dg/asan/on-error-callback-1.C
===================================================================
--- gcc/testsuite/g++.dg/asan/on-error-callback-1.C	(revision 0)
+++ gcc/testsuite/g++.dg/asan/on-error-callback-1.C	(revision 0)
@@ -0,0 +1,18 @@
+/* { dg-do run } */
+/* { dg-shouldfail "asan" } */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+extern "C"
+void __asan_on_error() {
+  fprintf(stderr, "__asan_on_error called");
+}
+
+int main() {
+  char *x = (char*)malloc(10 * sizeof(char));
+  free(x);
+  return x[5];
+}
+
+/* { dg-output "__asan_on_error called.*(\n|\r\n|\r)" } */
Index: gcc/testsuite/g++.dg/asan/initialization-blacklist-1.C
===================================================================
--- gcc/testsuite/g++.dg/asan/initialization-blacklist-1.C	(revision 0)
+++ gcc/testsuite/g++.dg/asan/initialization-blacklist-1.C	(revision 0)
@@ -0,0 +1,15 @@
+/* { dg-do run } */
+/* { dg-options "-asan-initialization-order" } */
+/* { dg-additional-sources "Helpers/initialization-blacklist-extra-1.C" } */
+
+// Function is defined in another TU.
+int readBadGlobal();
+int x = readBadGlobal();  // init-order bug.
+
+// Function is defined in another TU.
+int accessBadObject();
+int y = accessBadObject();  // init-order bug.
+
+int main(int argc, char **argv) {
+  return argc + x + y - 1;
+}
Index: gcc/testsuite/g++.dg/asan/asan.exp
===================================================================
--- gcc/testsuite/g++.dg/asan/asan.exp	(revision 193881)
+++ gcc/testsuite/g++.dg/asan/asan.exp	(working copy)
@@ -28,8 +28,124 @@ if ![check_effective_target_faddress_san
 dg-init
 asan_init
 
+# Compiling dlclose-test-1.C needs to build dlclose-test-so-1.so beforehand. 
+if { [info procs target_compile] != [list] \
+      && [info procs saved_asan_target_compile] == [list] } {
+  rename target_compile saved_asan_target_compile
+
+  proc target_compile { source dest type options } {
+    global srcdir subdir
+
+    if { [string match "*blacklist-1.c" $source] } {
+      set blacklist_options $options
+      set blist_tmp [glob $srcdir/c-c++-common/asan/Helpers/blacklist-1.tmp]
+      lappend blacklist_options "additional_flags=-asan-blacklist=$blist_tmp"
+      set result [eval [list saved_asan_target_compile \
+                        $source $dest $type $blacklist_options]]
+    } elseif { [string match "*initialization-blacklist-1.C" $source] } {
+      set blacklist_options $options
+      set blist_tmp [glob $srcdir/$subdir/Helpers/initialization-blacklist-1.tmp]
+      lappend blacklist_options "additional_flags=-asan-blacklist=$blist_tmp"
+      set result [eval [list saved_asan_target_compile \
+                        $source $dest $type $blacklist_options]]
+    } elseif { [string match "*dlclose-test-1.C" $source] } {
+      set dlclose_so_options $options
+      lappend dlclose_so_options "additional_flags=-fPIC -shared"
+      set auxfile [glob $srcdir/$subdir/SharedLibs/dlclose-test-1-so.C]
+      set result [eval [list saved_asan_target_compile \
+                        $auxfile \
+                        "dlclose-test-1.exe-so.so" \
+                        "executable" $dlclose_so_options]]
+      set result [eval [list saved_asan_target_compile \
+                        $source $dest $type $options]]
+      file delete "dlclose-test-1.exe-so.so"
+    } elseif { [string match "*shared-lib-test-1.C" $source] } {
+      set shared_lib_so_options $options
+      lappend shared_lib_so_options "additional_flags=-fPIC -shared"
+      set auxfile [glob $srcdir/$subdir/SharedLibs/shared-lib-test-1-so.C]
+      set result [eval [list saved_asan_target_compile \
+                        $auxfile \
+                        "shared-lib-test-1.exe-so.so" \
+                        "executable" $shared_lib_so_options]]
+      set result [eval [list saved_asan_target_compile \
+                        $source $dest $type $options]]
+      file delete "shared-lib-test-1.exe-so.so"
+    } elseif { [string match "*interface-symbols-1.c" $source] } {
+      set result [eval [list saved_asan_target_compile \
+                        $source "interface-symbols-1.exe" \
+                        "executable" $options]]
+      if { [string match "" $result] } {
+        set exefile [glob interface-symbols-1.exe]
+        set asan_interface_h [glob $srcdir/../../libsanitizer/include/sanitizer/asan_interface.h]
+        set script [glob $srcdir/c-c++-common/asan/Helpers/interface_symbols.sh]
+        set diff_result [exec sh $script $exefile $asan_interface_h]
+        if { ![string match "" $diff_result] } {
+          fail "$source -- diff result not empty: $diff_result"
+        }
+      }
+    } elseif { [string match "*initialization-bug-any-order-1.c" $source] } {
+      set auxfile [glob $srcdir/c-c++-common/asan/Helpers/initialization-bug-extra-1.c]
+      global subtest
+      if { [string match "subtest1" $subtest] } {
+        set source "$source $auxfile"
+      } else {
+        set source "$auxfile $source"
+      }
+      set result [eval [list saved_asan_target_compile $source $dest $type $options]]
+    } else {
+      set result [eval [list saved_asan_target_compile $source $dest $type $options]]
+    }
+    return $result
+  }
+}
+
+set default_asan_torture_options [list { -O0 -m32 } { -O1 -m32 } { -O2 -m32 } { -O3 -m32 } \
+                                  { -O0 -m64 } { -O1 -m64 } { -O2 -m64 } { -O3 -m64 }]
+
 # Main loop.
-gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.C $srcdir/c-c++-common/asan/*.c]] ""
+foreach srcfile [lsort [glob -nocomplain \
+                        $srcdir/$subdir/*.C \
+                        $srcdir/$subdir/linux/*.C \
+                        $srcdir/c-c++-common/asan/*.c \
+                        $srcdir/c-c++-common/asan/linux/*.c]] {
+  
+  set asan_torture_options $default_asan_torture_options
+  if { [string match "*deep-stack-uaf-1.C" $srcfile] } {
+    setenv ASAN_OPTIONS "malloc_context_size=120:redzone=512"
+  } elseif { [string match "*force-inline-opt0-1.c" $srcfile] } {
+    set asan_torture_options [list { -O0 -m64 } { -O1 -m64 }]
+  } elseif { [string match "*initialization-bug-1.c" $srcfile] } {
+    set asan_torture_options [list { -O0 -m32 } { -O0 -m64 }]
+  } elseif { [string match "*interface-symbols-1.c" $srcfile] 
+             || [string match "*symbolize-callback-1.C" $srcfile]
+             || [string match "*malloc-hook-1.C" $srcfile] } {
+    set asan_torture_options [list { -O2 }]
+  } elseif { [string match "*sleep-before-dying-1.c" $srcfile] } {
+    setenv ASAN_OPTIONS "sleep_before_dying=1"
+    set asan_torture_options [list { -O2 }]
+  } elseif { [string match "*strip-path-prefix-1.c" $srcfile] } {
+    setenv ASAN_OPTIONS "strip_path_prefix='/'"
+    set asan_torture_options [list { -O2 }]
+  } elseif { [string match "*initialization-bug-any-order-1.c" $srcfile] } {
+    set asan_torture_options [list { -O0 }]
+    set-torture-options $asan_torture_options
+    global subtest
+    set subtest "subtest1"
+    gcc-dg-runtest $srcfile ""
+    set subtest "subtest2"
+  } elseif { [string match "*rlimit-mmap-test-1.c" $srcfile] } {
+    set asan_torture_options [list { }]
+  }
+
+  set-torture-options $asan_torture_options
+  gcc-dg-runtest $srcfile ""
+
+  if { [string match "*deep-stack-uaf-1.C" $srcfile] 
+       || [string match "*sleep-before-dying-1.c" $srcfile]
+       || [string match "*strip-path-prefix-1.c" $srcfile] } {
+    unsetenv ASAN_OPTIONS
+  }
+}
 
 # All done.
 asan_finish
Index: gcc/testsuite/g++.dg/asan/initialization-nobug-1.C
===================================================================
--- gcc/testsuite/g++.dg/asan/initialization-nobug-1.C	(revision 0)
+++ gcc/testsuite/g++.dg/asan/initialization-nobug-1.C	(revision 0)
@@ -0,0 +1,51 @@
+// A collection of various initializers which shouldn't trip up initialization
+// order checking.  If successful, this will just return 0.
+
+/* { dg-do run } */
+/* { dg-options "--std=c++11 -asan-initialization-order" } */
+
+// 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; }
Index: gcc/testsuite/g++.dg/asan/large-func-test-1.C
===================================================================
--- gcc/testsuite/g++.dg/asan/large-func-test-1.C	(revision 0)
+++ gcc/testsuite/g++.dg/asan/large-func-test-1.C	(revision 0)
@@ -0,0 +1,46 @@
+/* { dg-do run } */
+/* { dg-shouldfail "asan" } */
+
+#include <stdlib.h>
+__attribute__((noinline))
+static void LargeFunction(int *x, int zero) {
+  x[0]++;
+  x[1]++;
+  x[2]++;
+  x[3]++;
+  x[4]++;
+  x[5]++;
+  x[6]++;
+  x[7]++;
+  x[8]++;
+  x[9]++;
+
+  x[zero + 111]++;  // we should report this exact line
+
+  x[10]++;
+  x[11]++;
+  x[12]++;
+  x[13]++;
+  x[14]++;
+  x[15]++;
+  x[16]++;
+  x[17]++;
+  x[18]++;
+  x[19]++;
+}
+
+int main(int argc, char **argv) {
+  int *x = new int[100];
+  LargeFunction(x, argc - 1);
+  delete x;
+}
+
+/* { dg-output "ERROR: AddressSanitizer heap-buffer-overflow on address\[^\n\r]*" } */
+/* { dg-output "0x\[0-9a-f\]+ at pc 0x\[0-9a-f\]+ bp 0x\[0-9a-f\]+ sp 0x\[0-9a-f\]+\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "READ of size 4 at 0x\[0-9a-f\]+ thread T0\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "    #0 0x\[0-9a-f\]+ (in \[^\n\r]*LargeFunction\[^\n\r]*(large-func-test-1.C:18|\[?\]\[?\]:0)|\[(\]).*(\n|\r\n|\r)" } */
+/* { dg-output "0x\[0-9a-f\]+ is located 44 bytes to the right of 400-byte region.*(\n|\r\n|\r)" } */
+/* { dg-output "allocated by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "    #0 0x\[0-9a-f\]+ (in _*(interceptor_|)malloc|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "    #1 0x\[0-9a-f\]+ (in (operator new|_Znwm)|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "    #2 0x\[0-9a-f\]+ (in _*main\[^\n\r]*(large-func-test-1.C:33|\[?\]\[?\]:0)|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */
Index: gcc/testsuite/g++.dg/asan/SharedLibs/dlclose-test-1-so.C
===================================================================
--- gcc/testsuite/g++.dg/asan/SharedLibs/dlclose-test-1-so.C	(revision 0)
+++ gcc/testsuite/g++.dg/asan/SharedLibs/dlclose-test-1-so.C	(revision 0)
@@ -0,0 +1,33 @@
+//===----------- dlclose-test-so.cc -----------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of AddressSanitizer, an address sanity checker.
+//
+// Regression test for
+// http://code.google.com/p/address-sanitizer/issues/detail?id=19
+//===----------------------------------------------------------------------===//
+#include <stdio.h>
+
+static int pad1;
+static int static_var;
+static int pad2;
+
+extern "C"
+int *get_address_of_static_var() {
+  return &static_var;
+}
+
+__attribute__((constructor))
+void at_dlopen() {
+  printf("%s: I am being dlopened\n", __FILE__);
+}
+__attribute__((destructor))
+void at_dlclose() {
+  printf("%s: I am being dlclosed\n", __FILE__);
+}
Index: gcc/testsuite/g++.dg/asan/SharedLibs/shared-lib-test-1-so.C
===================================================================
--- gcc/testsuite/g++.dg/asan/SharedLibs/shared-lib-test-1-so.C	(revision 0)
+++ gcc/testsuite/g++.dg/asan/SharedLibs/shared-lib-test-1-so.C	(revision 0)
@@ -0,0 +1,21 @@
+//===----------- shared-lib-test-so.cc --------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of AddressSanitizer, an address sanity checker.
+//
+//===----------------------------------------------------------------------===//
+#include <stdio.h>
+
+int pad[10];
+int GLOB[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+
+extern "C"
+void inc(int index) {
+  GLOB[index]++;
+}
Index: gcc/testsuite/g++.dg/asan/dlclose-test-1.C
===================================================================
--- gcc/testsuite/g++.dg/asan/dlclose-test-1.C	(revision 0)
+++ gcc/testsuite/g++.dg/asan/dlclose-test-1.C	(revision 0)
@@ -0,0 +1,67 @@
+// Regression test for
+// http://code.google.com/p/address-sanitizer/issues/detail?id=19
+// Bug description:
+// 1. application dlopens foo.so
+// 2. asan registers all globals from foo.so
+// 3. application dlcloses foo.so
+// 4. application mmaps some memory to the location where foo.so was before
+// 5. application starts using this mmaped memory, but asan still thinks there
+// are globals.
+// 6. BOOM
+
+/* { dg-do run } */
+
+#include <assert.h>
+#include <dlfcn.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/mman.h>
+
+#include <string>
+
+using std::string;
+
+static const int kPageSize = 4096;
+
+typedef int *(fun_t)();
+
+int main(int argc, char *argv[]) {
+  string path = string(argv[0]) + "-so.so";
+  printf("opening %s ... \n", path.c_str());
+  void *lib = dlopen(path.c_str(), RTLD_NOW);
+  if (!lib) {
+    printf("error in dlopen(): %s\n", dlerror());
+    return 1;
+  }
+  fun_t *get = (fun_t*)dlsym(lib, "get_address_of_static_var");
+  if (!get) {
+    printf("failed dlsym\n");
+    return 1;
+  }
+  int *addr = get();
+  //assert(((size_t)addr % 32) == 0);  // should be 32-byte aligned.
+  printf("addr: %p\n", addr);
+  addr[0] = 1;  // make sure we can write there.
+
+  // Now dlclose the shared library.
+  printf("attempting to dlclose\n");
+  if (dlclose(lib)) {
+    printf("failed to dlclose\n");
+    return 1;
+  }
+  // Now, the page where 'addr' is unmapped. Map it.
+  size_t page_beg = ((size_t)addr) & ~(kPageSize - 1);
+  void *res = mmap((void*)(page_beg), kPageSize,
+                   PROT_READ | PROT_WRITE,
+                   MAP_PRIVATE | MAP_ANON | MAP_FIXED | MAP_NORESERVE, 0, 0);
+  if (res == (char*)-1L) {
+    printf("failed to mmap\n");
+    return 1;
+  }
+  addr[1] = 2;  // BOOM (if the bug is not fixed).
+  printf("PASS\n");
+  // CHECK: PASS
+  return 0;
+}
+
+/* { dg-output "PASS" } */
Index: gcc/testsuite/g++.dg/asan/malloc-hook-1.C
===================================================================
--- gcc/testsuite/g++.dg/asan/malloc-hook-1.C	(revision 0)
+++ gcc/testsuite/g++.dg/asan/malloc-hook-1.C	(revision 0)
@@ -0,0 +1,24 @@
+/* { dg-do run } */
+#include <stdlib.h>
+#include <unistd.h>
+
+extern "C" {
+// Note: avoid calling functions that allocate memory in malloc/free
+// to avoid infinite recursion.
+void __asan_malloc_hook(void *ptr, size_t sz) {
+  write(1, "MallocHook\n", sizeof("MallocHook\n"));
+}
+void __asan_free_hook(void *ptr) {
+  write(1, "FreeHook\n", sizeof("FreeHook\n"));
+}
+}  // extern "C"
+
+int main() {
+  volatile int *x = new int;
+  *x = 0;
+  delete x;
+  return 0;
+}
+
+/* { dg-output "MallocHook(\n|\r\n|\r)" } */
+/* { dg-output "FreeHook(\n|\r\n|\r)" } */
Index: gcc/testsuite/g++.dg/asan/symbolize-callback-1.C
===================================================================
--- gcc/testsuite/g++.dg/asan/symbolize-callback-1.C	(revision 0)
+++ gcc/testsuite/g++.dg/asan/symbolize-callback-1.C	(revision 0)
@@ -0,0 +1,19 @@
+/* { dg-do run } */
+/* { dg-shouldfail "asan" } */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+extern "C"
+bool __asan_symbolize(const void *pc, char *out_buffer, int out_size) {
+  snprintf(out_buffer, out_size, "MySymbolizer");
+  return true;
+}
+
+int main() {
+  char *x = (char*)malloc(10 * sizeof(char));
+  free(x);
+  return x[5];
+}
+
+/* { dg-output "MySymbolizer" } */
Index: gcc/testsuite/g++.dg/asan/default-options-1.C
===================================================================
--- gcc/testsuite/g++.dg/asan/default-options-1.C	(revision 0)
+++ gcc/testsuite/g++.dg/asan/default-options-1.C	(revision 0)
@@ -0,0 +1,16 @@
+/* { dg-do run } */
+/* { dg-shouldfail "asan" } */
+
+const char *kAsanDefaultOptions="verbosity=1 foo=bar";
+
+extern "C"
+__attribute__((no_address_safety_analysis))
+const char *__asan_default_options() {
+  return kAsanDefaultOptions;
+}
+
+int main() {
+  return 0;
+}
+
+/* { dg-output "Using the defaults from __asan_default_options:.* foo=bar.*(\n|\r\n|\r)" } */
Index: gcc/testsuite/g++.dg/asan/deep-tail-call-1.C
===================================================================
--- gcc/testsuite/g++.dg/asan/deep-tail-call-1.C	(revision 0)
+++ gcc/testsuite/g++.dg/asan/deep-tail-call-1.C	(revision 0)
@@ -0,0 +1,20 @@
+/* { dg-do run } */
+/* { dg-options "-mno-omit-leaf-frame-pointer -fno-omit-frame-pointer -fno-optimize-sibling-calls" } */
+/* { dg-shouldfail "asan" } */
+
+int global[10];
+void __attribute__((noinline)) call4(int i) { global[i+10]++; }
+void __attribute__((noinline)) call3(int i) { call4(i); }
+void __attribute__((noinline)) call2(int i) { call3(i); }
+void __attribute__((noinline)) call1(int i) { call2(i); }
+int main(int argc, char **argv) {
+  call1(argc);
+  return global[0];
+}
+
+/* { dg-output "AddressSanitizer global-buffer-overflow.*(\n|\r\n|\r)" } */
+/* { dg-output "    #0 0x\[0-9a-f\]+ (in \[^\n\r]*call4\[^\n\r]*|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "    #1 0x\[0-9a-f\]+ (in \[^\n\r]*call3\[^\n\r]*|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "    #2 0x\[0-9a-f\]+ (in \[^\n\r]*call2\[^\n\r]*|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "    #3 0x\[0-9a-f\]+ (in \[^\n\r]*call1\[^\n\r]*|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "    #4 0x\[0-9a-f\]+ (in \[^\n\r]*main\[^\n\r]*|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */
Index: gcc/testsuite/g++.dg/asan/linux/interception-test-1.C
===================================================================
--- gcc/testsuite/g++.dg/asan/linux/interception-test-1.C	(revision 0)
+++ gcc/testsuite/g++.dg/asan/linux/interception-test-1.C	(revision 0)
@@ -0,0 +1,22 @@
+// ASan interceptor can be accessed with __interceptor_ prefix.
+
+/* { dg-do run } */
+/* { dg-shouldfail "asan" } */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+extern "C" long __interceptor_strtol(const char *nptr, char **endptr, int base);
+extern "C" long strtol(const char *nptr, char **endptr, int base) {
+  fprintf(stderr, "my_strtol_interceptor\n");
+  return __interceptor_strtol(nptr, endptr, base);
+}
+
+int main() {
+  char *x = (char*)malloc(10 * sizeof(char));
+  free(x);
+  return (int)strtol(x, 0, 10);
+}
+
+/* { dg-output "my_strtol_interceptor.*(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*heap-use-after-free" } */
Index: gcc/testsuite/g++.dg/asan/linux/interception-failure-test-1.C
===================================================================
--- gcc/testsuite/g++.dg/asan/linux/interception-failure-test-1.C	(revision 0)
+++ gcc/testsuite/g++.dg/asan/linux/interception-failure-test-1.C	(revision 0)
@@ -0,0 +1,21 @@
+// If user provides his own libc functions, ASan doesn't
+// intercept these functions.
+
+/* { dg-do run } */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+extern "C" long strtol(const char *nptr, char **endptr, int base) {
+  fprintf(stderr, "my_strtol_interceptor\n");
+  return 0;
+}
+
+int main() {
+  char *x = (char*)malloc(10 * sizeof(char));
+  free(x);
+  return (int)strtol(x, 0, 10);
+  // CHECK: my_strtol_interceptor
+}
+
+/* { dg-output "my_strtol_interceptor" } */
Index: gcc/testsuite/g++.dg/asan/linux/interception-malloc-test-1.C
===================================================================
--- gcc/testsuite/g++.dg/asan/linux/interception-malloc-test-1.C	(revision 0)
+++ gcc/testsuite/g++.dg/asan/linux/interception-malloc-test-1.C	(revision 0)
@@ -0,0 +1,23 @@
+// ASan interceptor can be accessed with __interceptor_ prefix.
+
+/* { dg-do run } */
+/* { dg-shouldfail "asan" } */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+
+extern "C" void *__interceptor_malloc(size_t size);
+extern "C" void *malloc(size_t size) {
+  write(2, "malloc call\n", sizeof("malloc call\n") - 1);
+  return __interceptor_malloc(size);
+}
+
+int main() {
+  char *x = (char*)malloc(10 * sizeof(char));
+  free(x);
+  return (int)strtol(x, 0, 10);
+}
+
+/* { dg-output "malloc call.*(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*heap-use-after-free" } */
Index: gcc/testsuite/lib/asan-dg.exp
===================================================================
--- gcc/testsuite/lib/asan-dg.exp	(revision 193881)
+++ gcc/testsuite/lib/asan-dg.exp	(working copy)
@@ -75,6 +75,7 @@ proc asan_init { args } {
 	    set link_flags "[asan_link_flags [get_multilibs ${TOOL_OPTIONS}]]"
 	} else {
 	    set link_flags "[asan_link_flags [get_multilibs]]"
+	    set link_flags "[asan_link_flags [get_multilibs -m32]] $link_flags"
 	}
     }
 
Index: gcc/testsuite/c-c++-common/asan/interface-symbols-1.c
===================================================================
--- gcc/testsuite/c-c++-common/asan/interface-symbols-1.c	(revision 0)
+++ gcc/testsuite/c-c++-common/asan/interface-symbols-1.c	(revision 0)
@@ -0,0 +1,24 @@
+// Check the presense of interface symbols in compiled file.
+
+// RUN: %clang -fsanitize=address -dead_strip -O2 %s -o %t.exe
+// RUN: nm %t.exe | egrep " [TW] " | sed "s/.* T //" | sed "s/.* W //" \
+// RUN:    | grep "__asan_" | sed "s/___asan_/__asan_/" > %t.symbols
+// RUN: cat %p/../../../include/sanitizer/asan_interface.h \
+// RUN:    | sed "s/\/\/.*//" | sed "s/typedef.*//" \
+// RUN:    | grep "__asan_.*(" | sed "s/.* __asan_/__asan_/;s/(.*//" \
+// RUN:    > %t.interface
+// RUN: echo __asan_report_load1 >> %t.interface
+// RUN: echo __asan_report_load2 >> %t.interface
+// RUN: echo __asan_report_load4 >> %t.interface
+// RUN: echo __asan_report_load8 >> %t.interface
+// RUN: echo __asan_report_load16 >> %t.interface
+// RUN: echo __asan_report_store1 >> %t.interface
+// RUN: echo __asan_report_store2 >> %t.interface
+// RUN: echo __asan_report_store4 >> %t.interface
+// RUN: echo __asan_report_store8 >> %t.interface
+// RUN: echo __asan_report_store16 >> %t.interface
+// RUN: cat %t.interface | sort -u | diff %t.symbols -
+
+/* { dg-options "-static-libasan -lpthread -ldl" } */
+
+int main() { return 0; }
Index: gcc/testsuite/c-c++-common/asan/strip-path-prefix-1.c
===================================================================
--- gcc/testsuite/c-c++-common/asan/strip-path-prefix-1.c	(revision 0)
+++ gcc/testsuite/c-c++-common/asan/strip-path-prefix-1.c	(revision 0)
@@ -0,0 +1,12 @@
+/* { dg-do run } */
+/* { dg-shouldfail "asan" } */
+
+#include <stdlib.h>
+int main() {
+  char *x = (char*)malloc(10 * sizeof(char));
+  free(x);
+  return x[5];
+}
+
+/* { dg-output "heap-use-after-free.*(\n|\r\n|\r)" } */
+/* { dg-output "    #0 0x\[0-9a-f\]+ \[(\]\[^/\]\[^\n\r]*(\n|\r\n|\r)" } */
Index: gcc/testsuite/c-c++-common/asan/force-inline-opt0-1.c
===================================================================
--- gcc/testsuite/c-c++-common/asan/force-inline-opt0-1.c	(revision 0)
+++ gcc/testsuite/c-c++-common/asan/force-inline-opt0-1.c	(revision 0)
@@ -0,0 +1,15 @@
+// This test checks that we are no instrumenting a memory access twice
+// (before and after inlining)
+
+/* { dg-do run } */
+/* { dg-options "-Wno-attributes" } */
+__attribute__((always_inline))
+void foo(int *x) {
+  *x = 0;
+}
+
+int main() {
+  int x;
+  foo(&x);
+  return x;
+}
Index: gcc/testsuite/c-c++-common/asan/null-deref-1.c
===================================================================
--- gcc/testsuite/c-c++-common/asan/null-deref-1.c	(revision 0)
+++ gcc/testsuite/c-c++-common/asan/null-deref-1.c	(revision 0)
@@ -0,0 +1,16 @@
+/* { dg-do run } */
+/* { dg-shouldfail "asan" } */
+
+__attribute__((noinline))
+static void NullDeref(int *ptr) {
+  ptr[10]++;
+}
+int main() {
+  NullDeref((int*)0);
+}
+
+/* { dg-output "ERROR: AddressSanitizer crashed on unknown address.*" } */
+/* { dg-output "0x\[0-9a-f\]+ .*pc 0x\[0-9a-f\]+\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "AddressSanitizer can not provide additional info.*(\n|\r\n|\r)" } */
+/* { dg-output "    #0 0x\[0-9a-f\]+ (in \[^\n\r]*NullDeref\[^\n\r]*(null_deref.cc:6|\[?\]\[?\]:0)|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "    #1 0x\[0-9a-f\]+ (in \[^\n\r]*main\[^\n\r]*(null_deref.cc:9|\[?\]\[?\]:0)|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */
Index: gcc/testsuite/c-c++-common/asan/global-overflow-1.c
===================================================================
--- gcc/testsuite/c-c++-common/asan/global-overflow-1.c	(revision 0)
+++ gcc/testsuite/c-c++-common/asan/global-overflow-1.c	(revision 0)
@@ -0,0 +1,20 @@
+/* { dg-do run } */
+/* { dg-shouldfail "asan" } */
+
+#include <string.h>
+int main(int argc, char **argv) {
+  static char XXX[10];
+  static char YYY[10];
+  static char ZZZ[10];
+  memset(XXX, 0, 10);
+  memset(YYY, 0, 10);
+  memset(ZZZ, 0, 10);
+  int res = YYY[argc * 10];  // BOOOM
+  res += XXX[argc] + ZZZ[argc];
+  return res;
+}
+
+/* { dg-output "READ of size 1 at 0x\[0-9a-f\]+ thread T0.*(\n|\r\n|\r)" } */
+/* { dg-output "    #0 0x\[0-9a-f\]+ (in _*main .*global-overflow.cc:18|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "0x\[0-9a-f\]+ is located 0 bytes to the right of global variable.*(\n|\r\n|\r)" } */
+/* { dg-output ".*YYY.* of size 10.*(\n|\r\n|\r)" } */
Index: gcc/testsuite/c-c++-common/asan/initialization-bug-1.c
===================================================================
--- gcc/testsuite/c-c++-common/asan/initialization-bug-1.c	(revision 0)
+++ gcc/testsuite/c-c++-common/asan/initialization-bug-1.c	(revision 0)
@@ -0,0 +1,50 @@
+// Test to make sure basic initialization order errors are caught.
+
+// RUN: %clangxx_asan -m64 -O0 %s %p/Helpers/initialization-bug-extra2.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-extra2.cc\
+// RUN:   -mllvm -asan-initialization-order -o %t && %t 2>&1 \
+// RUN:     | %symbolize | FileCheck %s
+
+/* { dg-do run } */
+/* { dg-shouldfail "asan" } */
+/* { dg-options "-asan-initialization-order" } */
+/* { dg-additional-sources "Helpers/initialization-bug-extra-1.c" } */
+
+// Do not test with optimization -- the error may be optimized away.
+
+#include <cstdio>
+
+// The structure of the test is:
+// "x", "y", "z" are dynamically initialized globals.
+// Value of "x" depends on "y", value of "y" depends on "z".
+// "x" and "z" are defined in this TU, "y" is defined in another one.
+// Thus we shoud stably report initialization order fiasco independently of
+// the translation unit order.
+
+int initZ() {
+  return 5;
+}
+int z = initZ();
+
+// '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.
+extern int y;
+int __attribute__((noinline)) initX() {
+  return y + 1;
+}
+
+// This initializer begins our initialization order problems.
+static int x = initX();
+
+int main() {
+  // ASan should have caused an exit before main runs.
+  return 0;
+}
+
+/* { dg-output "AddressSanitizer: initialization-order-fiasco.*(\n|\r\n|\r)" } */
+/* { dg-output "READ of size .* at 0x\[0-9a-f\]+ thread T0.*(\n|\r\n|\r)" } */
+/* { dg-output "0x\[0-9a-f\]+ is located 0 bytes inside of global variable .*(y|z).*(\n|\r\n|\r)" } */
Index: gcc/testsuite/c-c++-common/asan/strncpy-overflow-1.c
===================================================================
--- gcc/testsuite/c-c++-common/asan/strncpy-overflow-1.c	(revision 0)
+++ gcc/testsuite/c-c++-common/asan/strncpy-overflow-1.c	(revision 0)
@@ -0,0 +1,22 @@
+/* { dg-do run } */
+/* { dg-shouldfail "asan" } */
+
+#include <string.h>
+#include <stdlib.h>
+int main(int argc, char **argv) {
+  char *hello = (char*)malloc(6);
+  strcpy(hello, "hello");
+  char *short_buffer = (char*)malloc(9);
+  strncpy(short_buffer, hello, 10);  // BOOM
+  return short_buffer[8];
+}
+
+/* { dg-output "WRITE of size 1 at 0x\[0-9a-f\]+ thread T0\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "    #0 0x\[0-9a-f\]+ (in _*(interceptor_|)strncpy|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "    #1 0x\[0-9a-f\]+ (in _*main \[^\n\r]*(strncpy-overflow-1.c:10|\[?]\[?]:0)|\[(\]).*(\n|\r\n|\r)" } */
+/* { dg-output "0x\[0-9a-f\]+ is located 0 bytes to the right of 9-byte region\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "allocated by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "    #0 0x\[0-9a-f\]+ (in _*(interceptor_|)malloc|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "    #1 0x\[0-9a-f\]+ (in _*main \[^\n\r]*(strncpy-overflow-1.c:9|\[?]\[?]:0)|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */
+
+
Index: gcc/testsuite/c-c++-common/asan/stack-overflow-1.c
===================================================================
--- gcc/testsuite/c-c++-common/asan/stack-overflow-1.c	(revision 0)
+++ gcc/testsuite/c-c++-common/asan/stack-overflow-1.c	(revision 0)
@@ -0,0 +1,14 @@
+/* { dg-do run } */
+/* { dg-shouldfail "asan" } */
+
+#include <string.h>
+int main(int argc, char **argv) {
+  char x[10];
+  memset(x, 0, 10);
+  int res = x[argc * 10];  // BOOOM
+  return res;
+}
+
+/* { dg-output "READ of size 1 at 0x\[0-9a-f\]+ thread T0\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "    #0 0x\[0-9a-f\]+ (in _*main \[^\n\r]*(stack-overflow-1.c:8|\[?\]\[?\]:0)|\[(\]).*(\n|\r\n|\r)" } */
+/* { dg-output "Address 0x\[0-9a-f\]+ is\[^\n\r]*frame <main>" } */
Index: gcc/testsuite/c-c++-common/asan/blacklist-1.c
===================================================================
--- gcc/testsuite/c-c++-common/asan/blacklist-1.c	(revision 0)
+++ gcc/testsuite/c-c++-common/asan/blacklist-1.c	(revision 0)
@@ -0,0 +1,27 @@
+// Test the blacklist functionality of ASan
+
+/* { dg-do run } */
+/* { dg-additional-sources "Helpers/blacklist-extra-1.c" } */
+
+// 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-1.c, 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;
+}
Index: gcc/testsuite/c-c++-common/asan/use-after-free-1.c
===================================================================
--- gcc/testsuite/c-c++-common/asan/use-after-free-1.c	(revision 0)
+++ gcc/testsuite/c-c++-common/asan/use-after-free-1.c	(revision 0)
@@ -0,0 +1,21 @@
+/* { dg-do run } */
+/* { dg-shouldfail "asan" } */
+
+#include <stdlib.h>
+int main() {
+  char *x = (char*)malloc(10 * sizeof(char));
+  free(x);
+  return x[5];
+}
+
+/* { dg-output "ERROR: AddressSanitizer heap-use-after-free on address\[^\n\r]*" } */
+/* { dg-output "0x\[0-9a-f\]+ at pc 0x\[0-9a-f\]+ bp 0x\[0-9a-f\]+ sp 0x\[0-9a-f\]+\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "READ of size 1 at 0x\[0-9a-f\]+ thread T0\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "    #0 0x\[0-9a-f\]+ (in _*main \[^\n\r]*(use-after-free-1.c:8|\[?]\[?]:0)|\[(\]).*(\n|\r\n|\r)" } */
+/* { dg-output "0x\[0-9a-f\]+ is located 5 bytes inside of 10-byte region .0x\[0-9a-f\]+,0x\[0-9a-f\]+\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "freed by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "    #0 0x\[0-9a-f\]+ in \[^\n\r]*free\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "    #1 0x\[0-9a-f\]+ (in \[^\n\r]*main \[^\n\r]*(use-after-free-1.c:7|\[?]\[?]:0)|\[(\]).*(\n|\r\n|\r)" } */
+/* { dg-output "previously allocated by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "    #0 0x\[0-9a-f\]+ in \[^\n\r]*malloc\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "    #1 0x\[0-9a-f\]+ (in \[^\n\r]*main \[^\n\r]*(use-after-free-1.c:6|\[?]\[?]:0)|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */
Index: gcc/testsuite/c-c++-common/asan/sanity-check-pure-c-1.c
===================================================================
--- gcc/testsuite/c-c++-common/asan/sanity-check-pure-c-1.c	(revision 0)
+++ gcc/testsuite/c-c++-common/asan/sanity-check-pure-c-1.c	(revision 0)
@@ -0,0 +1,16 @@
+/* { dg-do run } */
+/* { dg-shouldfail "asan" } */
+
+#include <stdlib.h>
+int main() {
+  char *x = (char*)malloc(10 * sizeof(char));
+  free(x);
+  return x[5];
+}
+
+/* { dg-output "heap-use-after-free.*(\n|\r\n|\r)" } */
+/* { dg-output "    #0 \[^\n\r]*free\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "    #1 \[^\n\r]*(in main\[^\n\r]*(sanity-check-pure-c-1.c:7|\[?\]\[?\]:0)|\[(\]).*(\n|\r\n|\r)" } */
+/* { dg-output "    #0 \[^\n\r]*(interceptor_|)malloc\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "    #1 \[^\n\r]*(in main\[^\n\r]*(sanity-check-pure-c-1.c:6|\[?\]\[?\]:0)|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */
+
Index: gcc/testsuite/c-c++-common/asan/stack-use-after-return-1.c
===================================================================
--- gcc/testsuite/c-c++-common/asan/stack-use-after-return-1.c	(revision 0)
+++ gcc/testsuite/c-c++-common/asan/stack-use-after-return-1.c	(revision 0)
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+/* { dg-shouldfail "asan" } */
+#include <stdio.h>
+
+__attribute__((noinline))
+char *Ident(char *x) {
+  fprintf(stderr, "1: %p\n", x);
+  return x;
+}
+
+__attribute__((noinline))
+char *Func1() {
+  char local;
+  return Ident(&local);
+}
+
+__attribute__((noinline))
+void Func2(char *x) {
+  fprintf(stderr, "2: %p\n", x);
+  *x = 1;
+}
+
+int main(int argc, char **argv) {
+  Func2(Func1());
+  return 0;
+}
+
+/* { dg-output "WRITE of size 1 \[^\n\r]* thread T0" } */
+/* { dg-output "    #0\[^\n\r]*Func2\[^\n\r]*(stack-use-after-return.cc:28|\[?\]\[?\]:)" } */
+/* { dg-output "is located in frame <\[^\n\r]*Func1\[^\n\r]*> of T0's stack" } */
+
Index: gcc/testsuite/c-c++-common/asan/heap-overflow-1.c
===================================================================
--- gcc/testsuite/c-c++-common/asan/heap-overflow-1.c	(revision 0)
+++ gcc/testsuite/c-c++-common/asan/heap-overflow-1.c	(revision 0)
@@ -0,0 +1,20 @@
+/* { dg-do run } */
+/* { dg-shouldfail "asan" } */
+
+#include <stdlib.h>
+#include <string.h>
+int main(int argc, char **argv) {
+  char *x = (char*)malloc(10 * sizeof(char));
+  memset(x, 0, 10);
+  int res = x[argc * 10];  // BOOOM
+  free(x);
+  return res;
+}
+
+/* { dg-output "READ of size 1 at 0x\[0-9a-f\]+ thread T0.*(\n|\r\n|\r)" } */
+/* { dg-output "    #0 0x\[0-9a-f\]+ (in _*main .*(heap-overflow-1.c:9|\[?\]\[?\]:0)|\[(\]).*(\n|\r\n|\r)" } */
+/* { dg-output "0x\[0-9a-f\]+ is located 0 bytes to the right of 10-byte region\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "allocated by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "    #0 0x\[0-9a-f\]+ (in .*malloc|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "    #1 0x\[0-9a-f\]+ (in _*main .*(heap-overflow-1.c:7|\[?\]\[?\]:0)|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */
+
Index: gcc/testsuite/c-c++-common/asan/linux/initialization-bug-any-order-1.c
===================================================================
--- gcc/testsuite/c-c++-common/asan/linux/initialization-bug-any-order-1.c	(revision 0)
+++ gcc/testsuite/c-c++-common/asan/linux/initialization-bug-any-order-1.c	(revision 0)
@@ -0,0 +1,38 @@
+// Test to make sure basic initialization order errors are caught.
+// Check that on Linux initialization order bugs are caught
+// independently on order in which we list source files.
+
+// Do not test with optimization -- the error may be optimized away.
+
+/* { dg-do run } */
+/* { options "-asan-initialization-order" } */
+/* { dg-shouldfail "asan" } */
+
+#include <cstdio>
+
+int initZ() {
+  return 5;
+}
+int z = initZ();
+
+// '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.
+extern int y;
+int __attribute__((noinline)) initX() {
+  return y + 1;
+}
+
+// This initializer begins our initialization order problems.
+static int x = initX();
+
+int main() {
+  // ASan should have caused an exit before main runs.
+  return 0;
+}
+
+/* { dg-output "AddressSanitizer initialization-order-fiasco\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "READ of size \[^\n\r]* at 0x\[0-9a-f\]+ thread T0\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "    #0 0x\[0-9a-f\]+ (in \[^\n\r]*initX\[^\n\r]*(initialization-bug-any-order-1.c:31|\[?\]\[?\]:)|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "0x\[0-9a-f\]+ is located 0 bytes inside of global variable \[^\n\r]*y\[^\n\r]*" } */
Index: gcc/testsuite/c-c++-common/asan/linux/rlimit-mmap-test-1.c
===================================================================
--- gcc/testsuite/c-c++-common/asan/linux/rlimit-mmap-test-1.c	(revision 0)
+++ gcc/testsuite/c-c++-common/asan/linux/rlimit-mmap-test-1.c	(revision 0)
@@ -0,0 +1,21 @@
+// Check that we properly report mmap failure.
+// RUN: %clangxx_asan %s -o %t && %t 2>&1 | FileCheck %s
+
+/* { dg-do run } */
+/* { dg-shouldfail "asan" } */
+
+#include <stdlib.h>
+#include <assert.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+
+static volatile void *x;
+
+int main(int argc, char **argv) {
+  struct rlimit mmap_resource_limit = { 0, 0 };
+  assert(0 == setrlimit(RLIMIT_AS, &mmap_resource_limit));
+  x = malloc(10000000);
+  return 0;
+}
+
+/* { dg-output "AddressSanitizer is unable to mmap" } */
Index: gcc/testsuite/c-c++-common/asan/linux/swapcontext-test-1.c
===================================================================
--- gcc/testsuite/c-c++-common/asan/linux/swapcontext-test-1.c	(revision 0)
+++ gcc/testsuite/c-c++-common/asan/linux/swapcontext-test-1.c	(revision 0)
@@ -0,0 +1,61 @@
+// Check that ASan plays well with easy cases of makecontext/swapcontext.
+
+/* { dg-do run } */
+
+#include <stdio.h>
+#include <ucontext.h>
+#include <unistd.h>
+
+ucontext_t orig_context;
+ucontext_t child_context;
+
+void Child(int mode) {
+  char x[32] = {0};  // Stack gets poisoned.
+  printf("Child: %p\n", x);
+  // (a) Do nothing, just return to parent function.
+  // (b) Jump into the original function. Stack remains poisoned unless we do
+  //     something.
+  if (mode == 1) {
+    if (swapcontext(&child_context, &orig_context) < 0) {
+      perror("swapcontext");
+      _exit(0);
+    }
+  }
+}
+
+int Run(int arg, int mode) {
+  int i;
+  const int kStackSize = 1 << 20;
+  char child_stack[kStackSize + 1];
+  printf("Child stack: %p\n", child_stack);
+  // Setup child context.
+  getcontext(&child_context);
+  child_context.uc_stack.ss_sp = child_stack;
+  child_context.uc_stack.ss_size = kStackSize / 2;
+  if (mode == 0) {
+    child_context.uc_link = &orig_context;
+  }
+  makecontext(&child_context, (void (*)())Child, 1, mode);
+  if (swapcontext(&orig_context, &child_context) < 0) {
+    perror("swapcontext");
+    return 0;
+  }
+  // Touch childs's stack to make sure it's unpoisoned.
+  for (i = 0; i < kStackSize; i++) {
+    child_stack[i] = i;
+  }
+  return child_stack[arg];
+}
+
+int main(int argc, char **argv) {
+  int ret = 0;
+  ret += Run(argc - 1, 0);
+  printf("Test1 passed\n");
+  ret += Run(argc - 1, 1);
+  printf("Test2 passed\n");
+  return ret;
+}
+
+/* { dg-output "WARNING: ASan doesn't fully support makecontext/swapcontext.*" } */
+/* { dg-output "Test1 passed.*" } */
+/* { dg-output "Test2 passed.*" } */
Index: gcc/testsuite/c-c++-common/asan/linux/clone-test-1.c
===================================================================
--- gcc/testsuite/c-c++-common/asan/linux/clone-test-1.c	(revision 0)
+++ gcc/testsuite/c-c++-common/asan/linux/clone-test-1.c	(revision 0)
@@ -0,0 +1,46 @@
+// Regression test for:
+// http://code.google.com/p/address-sanitizer/issues/detail?id=37
+
+/* { dg-do run } */
+/* { dg-options "-D_GNU_SOURCE" } */
+/* { dg-shouldfail "asan" } */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sched.h>
+#include <sys/syscall.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+int Child(void *arg) {
+  char x[32] = {0};  // Stack gets poisoned.
+  printf("Child:  %p\n", x);
+  _exit(1);  // NoReturn, stack will remain unpoisoned unless we do something.
+}
+
+int main(int argc, char **argv) {
+  int i;
+  const int kStackSize = 1 << 20;
+  char child_stack[kStackSize + 1];
+  char *sp = child_stack + kStackSize;  // Stack grows down.
+  printf("Parent: %p\n", sp);
+  pid_t clone_pid = clone(Child, sp, CLONE_FILES | CLONE_VM, NULL, 0, 0, 0);
+  int status;
+  pid_t wait_result = waitpid(clone_pid, &status, __WCLONE);
+  if (wait_result < 0) {
+    perror("waitpid");
+    return 0;
+  }
+  if (wait_result == clone_pid && WIFEXITED(status)) {
+    // Make sure the child stack was indeed unpoisoned.
+    for (i = 0; i < kStackSize; i++)
+      child_stack[i] = i;
+    int ret = child_stack[argc - 1];
+    printf("PASSED\n");
+    return ret;
+  }
+  return 0;
+}
+
+/* { dg-output "PASSED" } */
Index: gcc/testsuite/c-c++-common/asan/sleep-before-dying-1.c
===================================================================
--- gcc/testsuite/c-c++-common/asan/sleep-before-dying-1.c	(revision 0)
+++ gcc/testsuite/c-c++-common/asan/sleep-before-dying-1.c	(revision 0)
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-shouldfail "asan" } */
+
+#include <stdlib.h>
+int main() {
+  char *x = (char*)malloc(10 * sizeof(char));
+  free(x);
+  return x[5];
+}
+
+/* { dg-output "Sleeping for 1 second" } */
Index: gcc/testsuite/c-c++-common/asan/Helpers/interface_symbols.sh
===================================================================
--- gcc/testsuite/c-c++-common/asan/Helpers/interface_symbols.sh	(revision 0)
+++ gcc/testsuite/c-c++-common/asan/Helpers/interface_symbols.sh	(revision 0)
@@ -0,0 +1,16 @@
+nm $1 | egrep " [TW] " | sed "s/.* T //" | sed "s/.* W //" \
+   | grep "__asan_" | sed "s/___asan_/__asan_/" > 1.t
+cat $2 | sed "s/\/\/.*//" | sed "s/typedef.*//" \
+| grep "__asan_.*(" | sed "s/.* __asan_/__asan_/;s/(.*//" > 2.t
+echo __asan_report_load1 >> 2.t
+echo __asan_report_load2 >> 2.t
+echo __asan_report_load4 >> 2.t
+echo __asan_report_load8 >> 2.t
+echo __asan_report_load16 >> 2.t
+echo __asan_report_store1 >> 2.t
+echo __asan_report_store2 >> 2.t
+echo __asan_report_store4 >> 2.t
+echo __asan_report_store8 >> 2.t
+echo __asan_report_store16 >> 2.t
+cat 2.t | sort -u | diff 1.t -
+rm 1.t 2.t

Property changes on: gcc/testsuite/c-c++-common/asan/Helpers/interface_symbols.sh
___________________________________________________________________
Added: svn:executable
   + *

Index: gcc/testsuite/c-c++-common/asan/Helpers/initialization-bug-extra-1.c
===================================================================
--- gcc/testsuite/c-c++-common/asan/Helpers/initialization-bug-extra-1.c	(revision 0)
+++ gcc/testsuite/c-c++-common/asan/Helpers/initialization-bug-extra-1.c	(revision 0)
@@ -0,0 +1,6 @@
+// 'z' is dynamically initialized global from different TU.
+extern int z;
+int __attribute__((noinline)) initY() {
+  return z + 1;
+}
+int y = initY();
Index: gcc/testsuite/c-c++-common/asan/Helpers/blacklist-1.tmp
===================================================================
--- gcc/testsuite/c-c++-common/asan/Helpers/blacklist-1.tmp	(revision 0)
+++ gcc/testsuite/c-c++-common/asan/Helpers/blacklist-1.tmp	(revision 0)
@@ -0,0 +1,3 @@
+fun:*brokenFunction*
+global:*badGlobal*
+src:*blacklist-extra-1.c
Index: gcc/testsuite/c-c++-common/asan/Helpers/blacklist-extra-1.c
===================================================================
--- gcc/testsuite/c-c++-common/asan/Helpers/blacklist-extra-1.c	(revision 0)
+++ gcc/testsuite/c-c++-common/asan/Helpers/blacklist-extra-1.c	(revision 0)
@@ -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
+}
