diff mbox

asan unit tests from llvm lit-test

Message ID CA+4CFy5jX04sXyvVNWx=jwch5PP6JE0amCK3XGntqKKNjr7SEQ@mail.gmail.com
State New
Headers show

Commit Message

Wei Mi Nov. 28, 2012, 9:15 a.m. UTC
Hi,

I try to migrate the left asan lit-tests from llvm (class3). This is a
preliminary version patch. Please forgive it has many mistakes.

A known problems: I hardcoded -m32 in (set link_flags
"[asan_link_flags [get_multilibs -m32]] $link_flags") in
gcc/testsuite/lib/asan-dg.exp to make 32 bit library path included in
ld_library_path. I don't know the elegant way to fix it.

Thanks,
Wei.

gcc/testsuite/
2012-11-28  Wei Mi  <wmi@google.com>

        * gcc.dg/asan/asan.exp: Case by case processing for some
special testcases.
        * g++.dg/asan/asan.exp: Likewise.
        * lib/asan-dg.exp: Likewise.
        * g++.dg/asan/linux: New, migrate from llvm asan lit-test.
        * g++.dg/asan/linux/interception-test-1.C: Likewise.
        * g++.dg/asan/linux/interception-failure-test-1.C: Likewise.
        * g++.dg/asan/linux/interception-malloc-test-1.C: Likewise.
        * g++.dg/asan/Helpers: Likewise.
        * g++.dg/asan/Helpers/initialization-blacklist-1.tmp: Likewise.
        * g++.dg/asan/Helpers/initialization-blacklist-extra-1.C: Likewise.
        * g++.dg/asan/deep-thread-stack-1.C: Likewise.
        * g++.dg/asan/shared-lib-test-1.C: Likewise.
        * g++.dg/asan/deep-stack-uaf-1.C: Likewise.
        * g++.dg/asan/on-error-callback-1.C: Likewise.
        * g++.dg/asan/initialization-blacklist-1.C: Likewise.
        * g++.dg/asan/initialization-nobug-1.C: Likewise.
        * g++.dg/asan/large-func-test-1.C: Likewise.
        * g++.dg/asan/SharedLibs: Likewise.
        * g++.dg/asan/SharedLibs/dlclose-test-1-so.C: Likewise.
        * g++.dg/asan/SharedLibs/shared-lib-test-1-so.C: Likewise.
        * g++.dg/asan/dlclose-test-1.C: Likewise.
        * g++.dg/asan/malloc-hook-1.C: Likewise.
        * g++.dg/asan/symbolize-callback-1.C: Likewise.
        * g++.dg/asan/default-options-1.C: Likewise.
        * g++.dg/asan/deep-tail-call-1.C: Likewise.
        * c-c++-common/asan/linux: Likewise.
        * c-c++-common/asan/linux/initialization-bug-any-order-1.c: Likewise.
        * c-c++-common/asan/linux/rlimit-mmap-test-1.c: Likewise.
        * c-c++-common/asan/linux/swapcontext-test-1.c: Likewise.
        * c-c++-common/asan/linux/clone-test-1.c: Likewise.
        * c-c++-common/asan/sleep-before-dying-1.c: Likewise.
        * c-c++-common/asan/Helpers: Likewise.
        * c-c++-common/asan/Helpers/blacklist-extra-1.c: Likewise.
        * c-c++-common/asan/Helpers/interface_symbols.sh: Likewise.
        * c-c++-common/asan/Helpers/initialization-bug-extra-1.c: Likewise.
        * c-c++-common/asan/Helpers/blacklist-1.tmp: Likewise.
        * c-c++-common/asan/interface-symbols-1.c: Likewise.
        * c-c++-common/asan/strip-path-prefix-1.c: Likewise.
        * c-c++-common/asan/force-inline-opt0-1.c: Likewise.
        * c-c++-common/asan/null-deref-1.c: Likewise.
        * c-c++-common/asan/global-overflow-1.c: Likewise.
        * c-c++-common/asan/initialization-bug-1.c: Likewise.
        * c-c++-common/asan/strncpy-overflow-1.c: Likewise.
        * c-c++-common/asan/stack-overflow-1.c: Likewise.
        * c-c++-common/asan/blacklist-1.c: Likewise.
        * c-c++-common/asan/use-after-free-1.c: Likewise.
        * c-c++-common/asan/sanity-check-pure-c-1.c: Likewise.
        * c-c++-common/asan/stack-use-after-return-1.c: Likewise.
        * c-c++-common/asan/heap-overflow-1.c: Likewise.

Comments

Konstantin Serebryany Nov. 28, 2012, 10:10 a.m. UTC | #1
I'd like to understand our long-term strategy wrt the asan/tsan tests in gcc.
Most of the tests we have today are not specific to the compiler and
so can potentially be used with any compiler.
The problem is the testing harness (FileCheck/gtest vs dejagnu).
I understand that using alien testing harnesses in the gcc tree might
be unacceptable,
but the other choice is doubled maintenance burden for tests.

I suggest we discuss this general problem first.

--kcc


On Wed, Nov 28, 2012 at 1:15 PM, Wei Mi <wmi@google.com> wrote:
> Hi,
>
> I try to migrate the left asan lit-tests from llvm (class3). This is a
> preliminary version patch. Please forgive it has many mistakes.
>
> A known problems: I hardcoded -m32 in (set link_flags
> "[asan_link_flags [get_multilibs -m32]] $link_flags") in
> gcc/testsuite/lib/asan-dg.exp to make 32 bit library path included in
> ld_library_path. I don't know the elegant way to fix it.
>
> Thanks,
> Wei.
>
> gcc/testsuite/
> 2012-11-28  Wei Mi  <wmi@google.com>
>
>         * gcc.dg/asan/asan.exp: Case by case processing for some
> special testcases.
>         * g++.dg/asan/asan.exp: Likewise.
>         * lib/asan-dg.exp: Likewise.
>         * g++.dg/asan/linux: New, migrate from llvm asan lit-test.
>         * g++.dg/asan/linux/interception-test-1.C: Likewise.
>         * g++.dg/asan/linux/interception-failure-test-1.C: Likewise.
>         * g++.dg/asan/linux/interception-malloc-test-1.C: Likewise.
>         * g++.dg/asan/Helpers: Likewise.
>         * g++.dg/asan/Helpers/initialization-blacklist-1.tmp: Likewise.
>         * g++.dg/asan/Helpers/initialization-blacklist-extra-1.C: Likewise.
>         * g++.dg/asan/deep-thread-stack-1.C: Likewise.
>         * g++.dg/asan/shared-lib-test-1.C: Likewise.
>         * g++.dg/asan/deep-stack-uaf-1.C: Likewise.
>         * g++.dg/asan/on-error-callback-1.C: Likewise.
>         * g++.dg/asan/initialization-blacklist-1.C: Likewise.
>         * g++.dg/asan/initialization-nobug-1.C: Likewise.
>         * g++.dg/asan/large-func-test-1.C: Likewise.
>         * g++.dg/asan/SharedLibs: Likewise.
>         * g++.dg/asan/SharedLibs/dlclose-test-1-so.C: Likewise.
>         * g++.dg/asan/SharedLibs/shared-lib-test-1-so.C: Likewise.
>         * g++.dg/asan/dlclose-test-1.C: Likewise.
>         * g++.dg/asan/malloc-hook-1.C: Likewise.
>         * g++.dg/asan/symbolize-callback-1.C: Likewise.
>         * g++.dg/asan/default-options-1.C: Likewise.
>         * g++.dg/asan/deep-tail-call-1.C: Likewise.
>         * c-c++-common/asan/linux: Likewise.
>         * c-c++-common/asan/linux/initialization-bug-any-order-1.c: Likewise.
>         * c-c++-common/asan/linux/rlimit-mmap-test-1.c: Likewise.
>         * c-c++-common/asan/linux/swapcontext-test-1.c: Likewise.
>         * c-c++-common/asan/linux/clone-test-1.c: Likewise.
>         * c-c++-common/asan/sleep-before-dying-1.c: Likewise.
>         * c-c++-common/asan/Helpers: Likewise.
>         * c-c++-common/asan/Helpers/blacklist-extra-1.c: Likewise.
>         * c-c++-common/asan/Helpers/interface_symbols.sh: Likewise.
>         * c-c++-common/asan/Helpers/initialization-bug-extra-1.c: Likewise.
>         * c-c++-common/asan/Helpers/blacklist-1.tmp: Likewise.
>         * c-c++-common/asan/interface-symbols-1.c: Likewise.
>         * c-c++-common/asan/strip-path-prefix-1.c: Likewise.
>         * c-c++-common/asan/force-inline-opt0-1.c: Likewise.
>         * c-c++-common/asan/null-deref-1.c: Likewise.
>         * c-c++-common/asan/global-overflow-1.c: Likewise.
>         * c-c++-common/asan/initialization-bug-1.c: Likewise.
>         * c-c++-common/asan/strncpy-overflow-1.c: Likewise.
>         * c-c++-common/asan/stack-overflow-1.c: Likewise.
>         * c-c++-common/asan/blacklist-1.c: Likewise.
>         * c-c++-common/asan/use-after-free-1.c: Likewise.
>         * c-c++-common/asan/sanity-check-pure-c-1.c: Likewise.
>         * c-c++-common/asan/stack-use-after-return-1.c: Likewise.
>         * c-c++-common/asan/heap-overflow-1.c: Likewise.
Jakub Jelinek Nov. 28, 2012, 10:14 a.m. UTC | #2
Hi!

On Wed, Nov 28, 2012 at 01:15:20AM -0800, Wei Mi wrote:
> I try to migrate the left asan lit-tests from llvm (class3). This is a
> preliminary version patch. Please forgive it has many mistakes.

Thanks for working on it.

> A known problems: I hardcoded -m32 in (set link_flags
> "[asan_link_flags [get_multilibs -m32]] $link_flags") in
> gcc/testsuite/lib/asan-dg.exp to make 32 bit library path included in
> ld_library_path. I don't know the elegant way to fix it.

That is wrong, no *.exp file should do anything with -m32/-m64.
If user wants to test both -m32 and -m64, it should be done through
RUNTESTFLAGS='--target_board=unix\{-m32,-m64\}'
on the command line of make check if desired (or any other options deemed
necessary to test).  Not all targets support both -m32 and -m64 (e.g. even
i686-linux doesn't), some targets have other ABI options (e.g. -m31/-m64 on
s390x, mips has more variants, etc.).  It must be user's choice what he
wants to test for what multilibs.

>         * g++.dg/asan/linux: New, migrate from llvm asan lit-test.
>         * g++.dg/asan/linux/interception-test-1.C: Likewise.
>         * g++.dg/asan/linux/interception-failure-test-1.C: Likewise.
>         * g++.dg/asan/linux/interception-malloc-test-1.C: Likewise.

Why the linux/ subdirectories (which you seem to run for all targets
anyway)?  That doesn't make any sense.  All tests that won't run on certain
targets because of some required features (whether it is e.g. dlopen, mmap,
pthreads) should be guarded, e.g.
// { dg-require-effective-target pthread }
or
/* { dg-run { target pthread } } */
and similar.  If some check_effective_target_* tcl test is missing, it can
be always added (e.g. dlopen doesn't have any, and you can't assume dlopen
works everywhere).

>         * g++.dg/asan/Helpers: Likewise.
>         * g++.dg/asan/Helpers/initialization-blacklist-1.tmp: Likewise.
>         * g++.dg/asan/Helpers/initialization-blacklist-extra-1.C: Likewise.

We aren't a CamelCase shop, I'd strongly prefer if we could avoid that
ugliness.  Ditto for SharedLibs/ etc. subdirs.  And why you need the subdirs
at all?  The usual way how to handle e.g. the dg-additional-sources is just
make sure the additional sources are either named in a way that doesn't
match the normal wildcard (for C++ e.g. *.cc instead of *.C) or add some dg
directive in there that it won't run, or be dg-do compile only test etc.

> +    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]]
> +    }

This is too ugly.  asan.exp shouldn't turn into yet another vect.exp, the
ideal is that for adding new tests you don't need to tweak any *.exp and add
exceptions for that, unless there is no other way.  So, preferrably in asan/
dir should stay tests that can be just handled the standard way, and there
can be some extra subdirectory that will handle hard to handle tests.
Say g++.dg/asan/special/ could have its own asan-special.exp or similar.
Note that e.g. for building shared libraries you really need to guard it
with appropriate target checks.

> +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 }]

As said earlier, no -m64/-m32 here, and if at all possible, no special
casing of tests in *.exp.  If you want to change the set of options
at which some test is run, i.e. you don't want to iterate over all the
options, just use dg-skip-if.  See
http://gcc.gnu.org/onlinedocs/gccint/Directives.html
for details about it.

> +  } elseif { [string match "*sleep-before-dying-1.c" $srcfile] } {
> +    setenv ASAN_OPTIONS "sleep_before_dying=1"
> +    set asan_torture_options [list { -O2 }]

For env options, I believe we don't have any dg directive right now to
set env vars for runtime tests, but the best way would be to add it,
dg-env-var or similar.  Or better yet, does libasan have a way to set
the options through some function call?  Then you wouldn't have to
set env vars...

> --- 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" } */

In C++ only tests, just use // comments instead of /* ... */
> +
> +#include <pthread.h>

That is exactly where you need to require effective target pthread...

> +/* { dg-options "-asan-initialization-order" } */

AFAIK gcc doesn't have that option, and if it had, it wouldn't be of this
form.  -fasan-initialization-order, --param asan-initialization-order=1 or
similar, perhaps, but not -asan-initialization-order.
But more generally, adding tests into GCC testsuite for unimplemented
features is undesirable, you can prepare the tests and post a rough patch
how they could look like, but it shouldn't be committed until the feature
is implemented.

> +/* { dg-additional-sources "Helpers/initialization-blacklist-extra-1.C" } */

> +//
> +//                     The LLVM Compiler Infrastructure

I believe we've been removing the above two lines from libsanitizer, so they
should probably be removed also from the tests?

> --- 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"

As has been said earlier, please don't do this.

> --- 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; }

This kind of test IMHO doesn't belong to the dejagnu testsuite,
if you really want to do it, it should be done somewhere in
libsanitizer/asan/ Makefile.am as part of building the library.

> --- 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))

Why -Wno-attributes?

> +#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];

argc/argv using tests are not portable to all targets, you can't rely
argc isn't e.g. zero.  Better just have some global variable, say,
int one = 1;
and at the beginning of main do asm volatile ("" : : : "memory");
to let compiler forget about the value it has, or just make the variable
volatile int one = 1;

> @@ -0,0 +1,22 @@
> +/* { dg-do run } */

I'd expect you want /* { dg-options "-fno-builtin-strncpy" } */
here, otherwise it is reported inside of main directly, rather than in the
strncpy interceptor.

> +/* { 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)" } */

	Jakub
Jakub Jelinek Nov. 28, 2012, 10:24 a.m. UTC | #3
On Wed, Nov 28, 2012 at 02:10:05PM +0400, Konstantin Serebryany wrote:
> I'd like to understand our long-term strategy wrt the asan/tsan tests in gcc.
> Most of the tests we have today are not specific to the compiler and
> so can potentially be used with any compiler.
> The problem is the testing harness (FileCheck/gtest vs dejagnu).
> I understand that using alien testing harnesses in the gcc tree might
> be unacceptable,

Yes, it is.

> but the other choice is doubled maintenance burden for tests.

There is no problem if somebody at google or elsewhere keeps running
say the llvm asan/tsan tests against gcc (but guess it needs to be adjusted
for that anyway, in the // RUN comments the tests are invoking
clang/clang++ etc., you'd need to either use a symlink clang -> gcc and
similar, or adjust comments), but we need some minimal testsuite inside of
gcc for the features, as GCC developers can't be required to run extra
testsuites and we need some way to ensure we don't regress, e.g. because of
an unrelated change etc.  I guess changes to existing llvm tests can be
monitored from time to time and the corresponding tests in gcc adjusted,
and also new tests could be ported as time permits.
And once we have a working testsuite, generally all bugfixes/new features
for the compiler should be acompanied by testcases.

	Jakub
Konstantin Serebryany Nov. 28, 2012, 10:40 a.m. UTC | #4
On Wed, Nov 28, 2012 at 2:24 PM, Jakub Jelinek <jakub@redhat.com> wrote:
> On Wed, Nov 28, 2012 at 02:10:05PM +0400, Konstantin Serebryany wrote:
>> I'd like to understand our long-term strategy wrt the asan/tsan tests in gcc.
>> Most of the tests we have today are not specific to the compiler and
>> so can potentially be used with any compiler.
>> The problem is the testing harness (FileCheck/gtest vs dejagnu).
>> I understand that using alien testing harnesses in the gcc tree might
>> be unacceptable,
>
> Yes, it is.
>
>> but the other choice is doubled maintenance burden for tests.
>
> There is no problem if somebody at google or elsewhere keeps running
> say the llvm asan/tsan tests against gcc (but guess it needs to be adjusted
> for that anyway, in the // RUN comments the tests are invoking
> clang/clang++ etc., you'd need to either use a symlink clang -> gcc and
> similar, or adjust comments), but we need some minimal testsuite inside of
> gcc for the features,

I fully agree about "minimal testsuite".
But, for example, porting the asan's gtest test (2+ KLOC) to another
harness is probably too much.

--kcc

>as GCC developers can't be required to run extra
> testsuites and we need some way to ensure we don't regress, e.g. because of
> an unrelated change etc.  I guess changes to existing llvm tests can be
> monitored from time to time and the corresponding tests in gcc adjusted,
> and also new tests could be ported as time permits.
> And once we have a working testsuite, generally all bugfixes/new features
> for the compiler should be acompanied by testcases.
>
>         Jakub
Jakub Jelinek Nov. 28, 2012, 11:03 a.m. UTC | #5
On Wed, Nov 28, 2012 at 02:40:55PM +0400, Konstantin Serebryany wrote:
> I fully agree about "minimal testsuite".
> But, for example, porting the asan's gtest test (2+ KLOC) to another
> harness is probably too much.

Depends on how significant changes to the test body are actually needed,
and if we could e.g. write a script that transforms the gtest test into
dejagnu test.
Say something minimal, like for each
  const char *uaf_string = "AddressSanitizer:.*heap-use-after-free";
  EXPECT_DEATH(uaf_test<U1>(1, 0), uaf_string);
replace that with
  DIE_IF(77, uaf_test<U1>(1, 0)); /* { dg-final { asan-die-if 77 "AddressSanitizer:.*heap-use-after-free" } } */
which would be essnetially
int die_if;
and at the beginning of main
  char *p = getenv ("ASAN_DIE_IF");
  if (p)
    die_if = atoi (p);
or so, then
#define DIE_IF(id, what) if (die_if == id) { what; }
where the test would be run normally first, then asan-die-if would
run it again (see e.g. gdb-test in guality.exp how it invokes gdb on the
test) with setenv ASAN_DIE_IF 77 (environment only to cope with target
boards that don't pass arguments, perhaps we could just ignore bare metal
targets for these kind of tests), and scan the output for the given regexp.
Problem with that is that unfortunately the regexps are runtime constructed,
aren't present as literals.
Or even slighly more involved solution would be to define
#define EXPECT_DEATH(x, y) \
  if (die_if == 0) \
    { \
      fprintf (stderr, "EXPECT_DEATH%d %s EXPECT_DEATHEND%d\n", \
	       die_if_counter, y, die_if_counter++); \
    } \
  else if (die_if_counter++ == die_if) \
    x
Then the test would be run once without ASAN_DIE_IF in environment (or =0),
that would produce output full of
EXPECT_DEATH1 AddressSanitizer:.*heap-use-after-free EXPECT_DEATHEND1
...
which tcl could parse, and figure from it that it should run the test
again 156 or how many times, with ASAN_DIE_IF from 1 to 156, and at each
iteration try to match the output against the regexp for that iteration.
Then you'd essentially just have to tweak a few lines at the start of the
test, includes, first few lines in main and that would be it.

	Jakub
Konstantin Serebryany Nov. 28, 2012, 11:13 a.m. UTC | #6
That's a bit scary (and will be slower than with gtest).
But if we can limit the changes by replacing
asan/tests/asan_test_config.h (and maybe some minimal other changes)
that may work.

--kcc

On Wed, Nov 28, 2012 at 3:03 PM, Jakub Jelinek <jakub@redhat.com> wrote:
> On Wed, Nov 28, 2012 at 02:40:55PM +0400, Konstantin Serebryany wrote:
>> I fully agree about "minimal testsuite".
>> But, for example, porting the asan's gtest test (2+ KLOC) to another
>> harness is probably too much.
>
> Depends on how significant changes to the test body are actually needed,
> and if we could e.g. write a script that transforms the gtest test into
> dejagnu test.
> Say something minimal, like for each
>   const char *uaf_string = "AddressSanitizer:.*heap-use-after-free";
>   EXPECT_DEATH(uaf_test<U1>(1, 0), uaf_string);
> replace that with
>   DIE_IF(77, uaf_test<U1>(1, 0)); /* { dg-final { asan-die-if 77 "AddressSanitizer:.*heap-use-after-free" } } */
> which would be essnetially
> int die_if;
> and at the beginning of main
>   char *p = getenv ("ASAN_DIE_IF");
>   if (p)
>     die_if = atoi (p);
> or so, then
> #define DIE_IF(id, what) if (die_if == id) { what; }
> where the test would be run normally first, then asan-die-if would
> run it again (see e.g. gdb-test in guality.exp how it invokes gdb on the
> test) with setenv ASAN_DIE_IF 77 (environment only to cope with target
> boards that don't pass arguments, perhaps we could just ignore bare metal
> targets for these kind of tests), and scan the output for the given regexp.
> Problem with that is that unfortunately the regexps are runtime constructed,
> aren't present as literals.
> Or even slighly more involved solution would be to define
> #define EXPECT_DEATH(x, y) \
>   if (die_if == 0) \
>     { \
>       fprintf (stderr, "EXPECT_DEATH%d %s EXPECT_DEATHEND%d\n", \
>                die_if_counter, y, die_if_counter++); \
>     } \
>   else if (die_if_counter++ == die_if) \
>     x
> Then the test would be run once without ASAN_DIE_IF in environment (or =0),
> that would produce output full of
> EXPECT_DEATH1 AddressSanitizer:.*heap-use-after-free EXPECT_DEATHEND1
> ...
> which tcl could parse, and figure from it that it should run the test
> again 156 or how many times, with ASAN_DIE_IF from 1 to 156, and at each
> iteration try to match the output against the regexp for that iteration.
> Then you'd essentially just have to tweak a few lines at the start of the
> test, includes, first few lines in main and that would be it.
>
>         Jakub
Jakub Jelinek Nov. 28, 2012, 11:24 a.m. UTC | #7
On Wed, Nov 28, 2012 at 12:03:27PM +0100, Jakub Jelinek wrote:
> Then the test would be run once without ASAN_DIE_IF in environment (or =0),
> that would produce output full of
> EXPECT_DEATH1 AddressSanitizer:.*heap-use-after-free EXPECT_DEATHEND1
> ...
> which tcl could parse, and figure from it that it should run the test
> again 156 or how many times, with ASAN_DIE_IF from 1 to 156, and at each
> iteration try to match the output against the regexp for that iteration.
> Then you'd essentially just have to tweak a few lines at the start of the
> test, includes, first few lines in main and that would be it.

That said, I find it very undesirable to put that many tests into one large
one, especially if it triggers undefined behavior like:
ATTRIBUTE_NO_ADDRESS_SAFETY_ANALYSIS
static void NoAddressSafety() {
  char *foo = new char[10];
  Ident(foo)[10] = 0;
  delete [] foo;
}

TEST(AddressSanitizer, AttributeNoAddressSafetyTest) {
  Ident(NoAddressSafety)();
}

As soon as you corrupt malloc state, anything can happen.  Things like
this should be verified by a compile only test that no instrumentation calls
have been added.

Looking at the test, there aren't just EXPECT_DEATH kinds of tests, and
running everything not guarded with EXPECT_DEATH macro many times might
be too expensive.  So perhaps it could run each TEST as a separate process,
by first just printing all test names that sould be run, then running
them one by one by asking for it in env, and for tests that would print
EPXECT_DEATHX ... EXPECT_DEATHENDX run that particular test again with
the requested EXPECT_DEATH counter.
Or run everything except EXPECT_DEATH macros first, and in EXPECT_DEATH
printouts print not just some counter, but also name of the current test,
and then when rerunning for some particular EXPECT_DEATH just run the
corresponding TEST and not all others.  Still, it is a couple of dozens
of lines in the test (defining the macros) and a little more than that
in tcl.

	Jakub
Konstantin Serebryany Nov. 28, 2012, 11:38 a.m. UTC | #8
On Wed, Nov 28, 2012 at 3:24 PM, Jakub Jelinek <jakub@redhat.com> wrote:
> On Wed, Nov 28, 2012 at 12:03:27PM +0100, Jakub Jelinek wrote:
>> Then the test would be run once without ASAN_DIE_IF in environment (or =0),
>> that would produce output full of
>> EXPECT_DEATH1 AddressSanitizer:.*heap-use-after-free EXPECT_DEATHEND1
>> ...
>> which tcl could parse, and figure from it that it should run the test
>> again 156 or how many times, with ASAN_DIE_IF from 1 to 156, and at each
>> iteration try to match the output against the regexp for that iteration.
>> Then you'd essentially just have to tweak a few lines at the start of the
>> test, includes, first few lines in main and that would be it.
>
> That said, I find it very undesirable to put that many tests into one large
> one, especially if it triggers undefined behavior like:
> ATTRIBUTE_NO_ADDRESS_SAFETY_ANALYSIS
> static void NoAddressSafety() {
>   char *foo = new char[10];
>   Ident(foo)[10] = 0;
>   delete [] foo;
> }

The behavior is undefined according to C++, but in the context of asan
build it is perfectly defined.


>
> TEST(AddressSanitizer, AttributeNoAddressSafetyTest) {
>   Ident(NoAddressSafety)();
> }
>
> As soon as you corrupt malloc state, anything can happen.  Things like
> this should be verified by a compile only test that no instrumentation calls
> have been added.

In LLVM we have such tests too.

--kcc

>
> Looking at the test, there aren't just EXPECT_DEATH kinds of tests, and
> running everything not guarded with EXPECT_DEATH macro many times might
> be too expensive.  So perhaps it could run each TEST as a separate process,
> by first just printing all test names that sould be run, then running
> them one by one by asking for it in env, and for tests that would print
> EPXECT_DEATHX ... EXPECT_DEATHENDX run that particular test again with
> the requested EXPECT_DEATH counter.
> Or run everything except EXPECT_DEATH macros first, and in EXPECT_DEATH
> printouts print not just some counter, but also name of the current test,
> and then when rerunning for some particular EXPECT_DEATH just run the
> corresponding TEST and not all others.  Still, it is a couple of dozens
> of lines in the test (defining the macros) and a little more than that
> in tcl.
>
>         Jakub
diff mbox

Patch

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
+}