diff options
author | Jakub Jelinek <jakub@gcc.gnu.org> | 2012-12-13 00:04:22 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2012-12-13 00:04:22 +0100 |
commit | 46cda8a06cf04acf404ab1cdf365993ca3fe4d16 (patch) | |
tree | f599eefbf765aa51ab18df6bffb69ac8e1d9817c | |
parent | f52f03c86c7daba3035aaba86f6de8141c30285b (diff) | |
download | gcc-46cda8a06cf04acf404ab1cdf365993ca3fe4d16.zip gcc-46cda8a06cf04acf404ab1cdf365993ca3fe4d16.tar.gz gcc-46cda8a06cf04acf404ab1cdf365993ca3fe4d16.tar.bz2 |
gcc-dg.exp (${tool}_load): Handle non-existing set_target_env_var the same as if it is empty list.
* lib/gcc-dg.exp (${tool}_load): Handle non-existing
set_target_env_var the same as if it is empty list.
(dg-set-target-env-var): Fix up error message.
(set-target-env-var): Record both preexisting env var values
as well as info that env wasn't set.
(restore-target-env-var): Iterate on reversed list, if second
sublist element is 1, setenv the env var to the third sublist
element, otherwise unsetenv it.
(gcc-dg-runtest): Don't initialize set_target_env_var.
(dg-test): Unset set_target_env_var if it was set.
* g++.dg/asan/deep-tail-call-1.C: Whitespace fixes. Don't rely
on argc being one.
* g++.dg/asan/interception-malloc-test-1.C: Only run on linux.
Whitespace fixes. Avoid unnecessary * sizeof(char).
* g++.dg/asan/deep-thread-stack-1.C: Add -lasan -lpthread to
dg-options. Whitespace fixes.
* g++.dg/asan/deep-stack-uaf-1.C: Skip for -flto. Whitespace fixes.
* g++.dg/asan/interception-test-1.C: Whitespace fixes.
* g++.dg/asan/interception-failure-test-1.C: Whitespace fixes.
Avoid unnecessary * sizeof(char). Remove // CHECK: comment.
* g++.dg/asan/default-options-1.C: Whitespace fixes.
* g++.dg/asan/symbolize-callback-1.C: Whitespace fixes. Make
first __asan_symbolize argument unnamed. Avoid unnecessary
* sizeof(char).
* g++.dg/asan/large-func-test-1.C: Whitespace fixes. Don't rely
on argc being one. Allow both _Znwj and _Znwm as operator new.
Ignore everything in the backtrace above operator new. Fix up
dg-output regexps.
* c-c++-common/asan/null-deref-1.c: Add -fno-omit-frame-pointer
and for x86 -mno-omit-leaf-frame-pointer. Fix up dg-output regexps.
* c-c++-common/asan/clone-test-1.c: Whitespace fixes. Return non-zero
on failures. Avoid pointless PASS dg-output check. Remove bogus
dg-shouldfail.
* c-c++-common/asan/sanity-check-pure-c-1.c: Fix up dg-output regexps.
Avoid unnecessary * sizeof(char).
* c-c++-common/asan/heap-overflow-1.c: Fix up dg-output regexps.
Don't rely on argc being one.
* c-c++-common/asan/sleep-before-dying-1.c: Whitespace fixes.
Avoid unnecessary * sizeof(char).
* c-c++-common/asan/rlimit-mmap-test-1.c: Whitespace fixes.
* c-c++-common/asan/stack-overflow-1.c: Fix up dg-output regexps.
* c-c++-common/asan/global-overflow-1.c: Add -fno-builtin-memset.
Fix up dg-output regexps.
* c-c++-common/asan/strncpy-overflow-1.c: Fix up dg-output regexps.
* c-c++-common/asan/memcmp-1.c: Don't rely on argc being one.
* c-c++-common/asan/use-after-free-1.c: Fix up dg-output regexps.
* c-c++-common/asan/swapcontext-test-1.c: Don't rely on argc being
one.
* c-c++-common/asan/force-inline-opt0-1.c: Remove dg-skip-if.
* c-c++-common/asan/strip-path-prefix-1.c: Whitespace fixes.
Avoid unnecessary * sizeof(char).
2012-12-12 Wei Mi <wmi@google.com>
* lib/target-supports.exp (check_effective_target_dlopen,
check_effective_target_clone, check_effective_target_setrlimit,
check_effective_target_swapcontext): New procedures.
* lib/gcc-dg.exp (${tool}_load): Handle dg-set-target-env-var.
(dg-set-target-env-var, set-target-env-var,
restore-target-env-var): New procedures.
(gcc-dg-runtest): Set set_target_env_var.
* g++.dg/asan/symbolize-callback-1.C: New test.
* g++.dg/asan/shared-lib-test-1-so.cc: New file.
* g++.dg/asan/deep-tail-call-1.C: New test.
* g++.dg/asan/default-options-1.C: New test.
* g++.dg/asan/interception-test-1.C: New test.
* g++.dg/asan/dlclose-test-1-so.cc: New file.
* g++.dg/asan/deep-thread-stack-1.C: New test.
* g++.dg/asan/interception-malloc-test-1.C: New test.
* g++.dg/asan/deep-stack-uaf-1.C: New test.
* g++.dg/asan/large-func-test-1.C: New test.
* g++.dg/asan/interception-failure-test-1.C: New test.
* c-c++-common/asan/strip-path-prefix-1.c: New test.
* c-c++-common/asan/force-inline-opt0-1.c: New test.
* c-c++-common/asan/swapcontext-test-1.c: New test.
* c-c++-common/asan/null-deref-1.c: New test.
* c-c++-common/asan/global-overflow-1.c: New test.
* c-c++-common/asan/strncpy-overflow-1.c: New test.
* c-c++-common/asan/rlimit-mmap-test-1.c: New test.
* c-c++-common/asan/stack-overflow-1.c: New test.
* c-c++-common/asan/use-after-free-1.c: New test.
* c-c++-common/asan/sanity-check-pure-c-1.c: New test.
* c-c++-common/asan/clone-test-1.c: New test.
* c-c++-common/asan/heap-overflow-1.c: New test.
* c-c++-common/asan/sleep-before-dying-1.c: New test.
From-SVN: r194458
28 files changed, 805 insertions, 4 deletions
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 097011d..80981f6 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,92 @@ +2012-12-12 Jakub Jelinek <jakub@redhat.com> + + * lib/gcc-dg.exp (${tool}_load): Handle non-existing + set_target_env_var the same as if it is empty list. + (dg-set-target-env-var): Fix up error message. + (set-target-env-var): Record both preexisting env var values + as well as info that env wasn't set. + (restore-target-env-var): Iterate on reversed list, if second + sublist element is 1, setenv the env var to the third sublist + element, otherwise unsetenv it. + (gcc-dg-runtest): Don't initialize set_target_env_var. + (dg-test): Unset set_target_env_var if it was set. + + * g++.dg/asan/deep-tail-call-1.C: Whitespace fixes. Don't rely + on argc being one. + * g++.dg/asan/interception-malloc-test-1.C: Only run on linux. + Whitespace fixes. Avoid unnecessary * sizeof(char). + * g++.dg/asan/deep-thread-stack-1.C: Add -lasan -lpthread to + dg-options. Whitespace fixes. + * g++.dg/asan/deep-stack-uaf-1.C: Skip for -flto. Whitespace fixes. + * g++.dg/asan/interception-test-1.C: Whitespace fixes. + * g++.dg/asan/interception-failure-test-1.C: Whitespace fixes. + Avoid unnecessary * sizeof(char). Remove // CHECK: comment. + * g++.dg/asan/default-options-1.C: Whitespace fixes. + * g++.dg/asan/symbolize-callback-1.C: Whitespace fixes. Make + first __asan_symbolize argument unnamed. Avoid unnecessary + * sizeof(char). + * g++.dg/asan/large-func-test-1.C: Whitespace fixes. Don't rely + on argc being one. Allow both _Znwj and _Znwm as operator new. + Ignore everything in the backtrace above operator new. Fix up + dg-output regexps. + * c-c++-common/asan/null-deref-1.c: Add -fno-omit-frame-pointer + and for x86 -mno-omit-leaf-frame-pointer. Fix up dg-output regexps. + * c-c++-common/asan/clone-test-1.c: Whitespace fixes. Return non-zero + on failures. Avoid pointless PASS dg-output check. Remove bogus + dg-shouldfail. + * c-c++-common/asan/sanity-check-pure-c-1.c: Fix up dg-output regexps. + Avoid unnecessary * sizeof(char). + * c-c++-common/asan/heap-overflow-1.c: Fix up dg-output regexps. + Don't rely on argc being one. + * c-c++-common/asan/sleep-before-dying-1.c: Whitespace fixes. + Avoid unnecessary * sizeof(char). + * c-c++-common/asan/rlimit-mmap-test-1.c: Whitespace fixes. + * c-c++-common/asan/stack-overflow-1.c: Fix up dg-output regexps. + * c-c++-common/asan/global-overflow-1.c: Add -fno-builtin-memset. + Fix up dg-output regexps. + * c-c++-common/asan/strncpy-overflow-1.c: Fix up dg-output regexps. + * c-c++-common/asan/memcmp-1.c: Don't rely on argc being one. + * c-c++-common/asan/use-after-free-1.c: Fix up dg-output regexps. + * c-c++-common/asan/swapcontext-test-1.c: Don't rely on argc being + one. + * c-c++-common/asan/force-inline-opt0-1.c: Remove dg-skip-if. + * c-c++-common/asan/strip-path-prefix-1.c: Whitespace fixes. + Avoid unnecessary * sizeof(char). + +2012-12-12 Wei Mi <wmi@google.com> + + * lib/target-supports.exp (check_effective_target_dlopen, + check_effective_target_clone, check_effective_target_setrlimit, + check_effective_target_swapcontext): New procedures. + * lib/gcc-dg.exp (${tool}_load): Handle dg-set-target-env-var. + (dg-set-target-env-var, set-target-env-var, + restore-target-env-var): New procedures. + (gcc-dg-runtest): Set set_target_env_var. + * g++.dg/asan/symbolize-callback-1.C: New test. + * g++.dg/asan/shared-lib-test-1-so.cc: New file. + * g++.dg/asan/deep-tail-call-1.C: New test. + * g++.dg/asan/default-options-1.C: New test. + * g++.dg/asan/interception-test-1.C: New test. + * g++.dg/asan/dlclose-test-1-so.cc: New file. + * g++.dg/asan/deep-thread-stack-1.C: New test. + * g++.dg/asan/interception-malloc-test-1.C: New test. + * g++.dg/asan/deep-stack-uaf-1.C: New test. + * g++.dg/asan/large-func-test-1.C: New test. + * g++.dg/asan/interception-failure-test-1.C: New test. + * c-c++-common/asan/strip-path-prefix-1.c: New test. + * c-c++-common/asan/force-inline-opt0-1.c: New test. + * c-c++-common/asan/swapcontext-test-1.c: New test. + * c-c++-common/asan/null-deref-1.c: New test. + * c-c++-common/asan/global-overflow-1.c: New test. + * c-c++-common/asan/strncpy-overflow-1.c: New test. + * c-c++-common/asan/rlimit-mmap-test-1.c: New test. + * c-c++-common/asan/stack-overflow-1.c: New test. + * c-c++-common/asan/use-after-free-1.c: New test. + * c-c++-common/asan/sanity-check-pure-c-1.c: New test. + * c-c++-common/asan/clone-test-1.c: New test. + * c-c++-common/asan/heap-overflow-1.c: New test. + * c-c++-common/asan/sleep-before-dying-1.c: New test. + 2012-12-12 Steve Ellcey <sellcey@mips.com> * gcc.dg/pr55150-2.c: Add pic support check. diff --git a/gcc/testsuite/c-c++-common/asan/clone-test-1.c b/gcc/testsuite/c-c++-common/asan/clone-test-1.c new file mode 100644 index 0000000..d9acc0d --- /dev/null +++ b/gcc/testsuite/c-c++-common/asan/clone-test-1.c @@ -0,0 +1,45 @@ +/* Regression test for: + http://code.google.com/p/address-sanitizer/issues/detail?id=37 */ + +/* { dg-do run { target { *-*-linux* } } } */ +/* { dg-require-effective-target clone } */ +/* { dg-options "-D_GNU_SOURCE" } */ + +#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. */ +} + +volatile int zero = 0; + +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 1; + } + 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[zero]; + return ret; + } + return 1; +} diff --git a/gcc/testsuite/c-c++-common/asan/force-inline-opt0-1.c b/gcc/testsuite/c-c++-common/asan/force-inline-opt0-1.c new file mode 100644 index 0000000..0576155 --- /dev/null +++ b/gcc/testsuite/c-c++-common/asan/force-inline-opt0-1.c @@ -0,0 +1,16 @@ +/* This test checks that we are no instrumenting a memory access twice + (before and after inlining) */ + +/* { dg-do compile } */ +/* { dg-final { scan-assembler-not "__asan_report_load" } } */ + +__attribute__((always_inline)) +inline void foo(int *x) { + *x = 0; +} + +int main() { + int x; + foo(&x); + return x; +} diff --git a/gcc/testsuite/c-c++-common/asan/global-overflow-1.c b/gcc/testsuite/c-c++-common/asan/global-overflow-1.c new file mode 100644 index 0000000..b70c300 --- /dev/null +++ b/gcc/testsuite/c-c++-common/asan/global-overflow-1.c @@ -0,0 +1,23 @@ +/* { dg-do run } */ +/* { dg-options "-fno-builtin-memset" } */ +/* { dg-shouldfail "asan" } */ + +#include <string.h> +volatile int ten = 10; + +int main() { + 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[ten]; /* BOOOM */ + res += XXX[ten/10] + ZZZ[ten/10]; + 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 (\[^\n\r]*global-overflow-1.c:15|\[^\n\r]*:0)|\[(\])\[^\n\r]*(\n|\r\n|\r).*" } */ +/* { dg-output "0x\[0-9a-f\]+ is located 0 bytes to the right of global variable" } */ +/* { dg-output ".*YYY\[^\n\r]* of size 10\[^\n\r]*(\n|\r\n|\r)" } */ diff --git a/gcc/testsuite/c-c++-common/asan/heap-overflow-1.c b/gcc/testsuite/c-c++-common/asan/heap-overflow-1.c new file mode 100644 index 0000000..7e9f54b --- /dev/null +++ b/gcc/testsuite/c-c++-common/asan/heap-overflow-1.c @@ -0,0 +1,21 @@ +/* { dg-do run } */ +/* { dg-options "-fno-builtin-malloc -fno-builtin-free -fno-builtin-memset" } */ +/* { dg-shouldfail "asan" } */ + +#include <stdlib.h> +#include <string.h> +volatile int ten = 10; +int main(int argc, char **argv) { + char *x = (char*)malloc(10); + memset(x, 0, 10); + int res = x[ten]; /* 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 (\[^\n\r]*heap-overflow-1.c:11|\[^\n\r]*: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 _*(interceptor_|)malloc|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output " #1 0x\[0-9a-f\]+ (in _*main (\[^\n\r]*heap-overflow-1.c:9|\[^\n\r]*:0)|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ diff --git a/gcc/testsuite/c-c++-common/asan/memcmp-1.c b/gcc/testsuite/c-c++-common/asan/memcmp-1.c index a23ff23..03f32e9 100644 --- a/gcc/testsuite/c-c++-common/asan/memcmp-1.c +++ b/gcc/testsuite/c-c++-common/asan/memcmp-1.c @@ -4,12 +4,14 @@ #include <string.h> +volatile int one = 1; + int -main (int argc, char **argv) +main () { - char a1[] = {argc, 2, 3, 4}; - char a2[] = {1, 2*argc, 3, 4}; - int res = memcmp (a1, a2, 5 + argc); + char a1[] = {one, 2, 3, 4}; + char a2[] = {1, 2*one, 3, 4}; + int res = memcmp (a1, a2, 5 + one); return res; } diff --git a/gcc/testsuite/c-c++-common/asan/null-deref-1.c b/gcc/testsuite/c-c++-common/asan/null-deref-1.c new file mode 100644 index 0000000..6a849bf --- /dev/null +++ b/gcc/testsuite/c-c++-common/asan/null-deref-1.c @@ -0,0 +1,23 @@ +/* { dg-do run } */ +/* { dg-options "-fno-omit-frame-pointer" } */ +/* { dg-additional-options "-mno-omit-leaf-frame-pointer" { target { i?86-*-* x86_64-*-* } } } */ +/* { dg-shouldfail "asan" } */ + +__attribute__((noinline, noclone)) +static void +NullDeref(int *ptr) +{ + ptr[10]++; +} + +int main() +{ + NullDeref((int*)0); + return 0; +} + +/* { dg-output "ERROR: AddressSanitizer:? SEGV on unknown address\[^\n\r]*" } */ +/* { dg-output "0x\[0-9a-f\]+ \[^\n\r]*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]* (\[^\n\r]*null-deref-1.c:10|\[^\n\r]*:0)|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output " #1 0x\[0-9a-f\]+ (in _*main (\[^\n\r]*null-deref-1.c:15|\[^\n\r]*:0)|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ diff --git a/gcc/testsuite/c-c++-common/asan/rlimit-mmap-test-1.c b/gcc/testsuite/c-c++-common/asan/rlimit-mmap-test-1.c new file mode 100644 index 0000000..212db3b --- /dev/null +++ b/gcc/testsuite/c-c++-common/asan/rlimit-mmap-test-1.c @@ -0,0 +1,21 @@ +/* Check that we properly report mmap failure. */ + +/* { dg-do run { target setrlimit } } */ +/* { dg-skip-if "" { *-*-* } { "*" } { "-O0" } } */ +/* { 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 }; + if (setrlimit(RLIMIT_AS, &mmap_resource_limit)) return 1; + x = malloc(10000000); + return 0; +} + +/* { dg-output "AddressSanitizer is unable to mmap" } */ diff --git a/gcc/testsuite/c-c++-common/asan/sanity-check-pure-c-1.c b/gcc/testsuite/c-c++-common/asan/sanity-check-pure-c-1.c new file mode 100644 index 0000000..78d15e1 --- /dev/null +++ b/gcc/testsuite/c-c++-common/asan/sanity-check-pure-c-1.c @@ -0,0 +1,16 @@ +/* { dg-do run } */ +/* { dg-options "-fno-builtin-malloc -fno-builtin-free" } */ +/* { dg-shouldfail "asan" } */ + +#include <stdlib.h> +int main() { + char *x = (char*)malloc(10); + free(x); + return x[5]; +} + +/* { dg-output "heap-use-after-free.*(\n|\r\n|\r)" } */ +/* { dg-output " #0 \[^\n\r]*(in _*(interceptor_|)free|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output " #1 \[^\n\r]*(in _*main (\[^\n\r]*sanity-check-pure-c-1.c:8|\[^\n\r]*:0)|\[(\]).*(\n|\r\n|\r)" } */ +/* { dg-output " #0 \[^\n\r]*(in _*(interceptor_|)malloc|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output " #1 \[^\n\r]*(in _*main (\[^\n\r]*sanity-check-pure-c-1.c:7|\[^\n\r]*:0)|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ diff --git a/gcc/testsuite/c-c++-common/asan/sleep-before-dying-1.c b/gcc/testsuite/c-c++-common/asan/sleep-before-dying-1.c new file mode 100644 index 0000000..e508859 --- /dev/null +++ b/gcc/testsuite/c-c++-common/asan/sleep-before-dying-1.c @@ -0,0 +1,14 @@ +/* { dg-do run } */ +/* { dg-set-target-env-var ASAN_OPTIONS "sleep_before_dying=1" } */ +/* { dg-skip-if "" { *-*-* } { "*" } { "-O2" } } */ +/* { dg-options "-fno-builtin-malloc -fno-builtin-free" } */ +/* { dg-shouldfail "asan" } */ + +#include <stdlib.h> +int main() { + char *x = (char*)malloc(10); + free(x); + return x[5]; +} + +/* { dg-output "Sleeping for 1 second" } */ diff --git a/gcc/testsuite/c-c++-common/asan/stack-overflow-1.c b/gcc/testsuite/c-c++-common/asan/stack-overflow-1.c new file mode 100644 index 0000000..c44370f --- /dev/null +++ b/gcc/testsuite/c-c++-common/asan/stack-overflow-1.c @@ -0,0 +1,18 @@ +/* { dg-do run } */ +/* { dg-options "-fno-builtin-memset" } */ +/* { dg-shouldfail "asan" } */ + +volatile int ten = 10; + +#include <string.h> + +int main() { + char x[10]; + memset(x, 0, 10); + int res = x[ten]; /* 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:12|\[^\n\r]*:0)|\[(\]).*(\n|\r\n|\r)" } */ +/* { dg-output "Address 0x\[0-9a-f\]+ is\[^\n\r]*frame <main>" } */ diff --git a/gcc/testsuite/c-c++-common/asan/strip-path-prefix-1.c b/gcc/testsuite/c-c++-common/asan/strip-path-prefix-1.c new file mode 100644 index 0000000..ea8e933 --- /dev/null +++ b/gcc/testsuite/c-c++-common/asan/strip-path-prefix-1.c @@ -0,0 +1,15 @@ +/* { dg-do run } */ +/* { dg-skip-if "" { *-*-* } { "*" } { "-O2" } } */ +/* { dg-set-target-env-var ASAN_OPTIONS "strip_path_prefix='/'" } */ +/* { dg-options "-fno-builtin-malloc -fno-builtin-free" } */ +/* { dg-shouldfail "asan" } */ + +#include <stdlib.h> +int main() { + char *x = (char*)malloc(10); + 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)" } */ diff --git a/gcc/testsuite/c-c++-common/asan/strncpy-overflow-1.c b/gcc/testsuite/c-c++-common/asan/strncpy-overflow-1.c new file mode 100644 index 0000000..c8c2883 --- /dev/null +++ b/gcc/testsuite/c-c++-common/asan/strncpy-overflow-1.c @@ -0,0 +1,21 @@ +/* { dg-do run } */ +/* { dg-options "-fno-builtin-malloc -fno-builtin-strncpy" } */ +/* { 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:11|\[^\n\r]*: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:10|\[^\n\r]*:0)|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ diff --git a/gcc/testsuite/c-c++-common/asan/swapcontext-test-1.c b/gcc/testsuite/c-c++-common/asan/swapcontext-test-1.c new file mode 100644 index 0000000..23d3db0 --- /dev/null +++ b/gcc/testsuite/c-c++-common/asan/swapcontext-test-1.c @@ -0,0 +1,63 @@ +/* Check that ASan plays well with easy cases of makecontext/swapcontext. */ + +/* { dg-do run { target swapcontext } } */ + +#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]; +} + +volatile int zero = 0; + +int main(int argc, char **argv) { + int ret = 0; + ret += Run(zero, 0); + printf("Test1 passed\n"); + ret += Run(zero, 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.*" } */ diff --git a/gcc/testsuite/c-c++-common/asan/use-after-free-1.c b/gcc/testsuite/c-c++-common/asan/use-after-free-1.c new file mode 100644 index 0000000..939feeb --- /dev/null +++ b/gcc/testsuite/c-c++-common/asan/use-after-free-1.c @@ -0,0 +1,22 @@ +/* { dg-do run } */ +/* { dg-options "-fno-builtin-malloc -fno-builtin-free" } */ +/* { dg-shouldfail "asan" } */ + +#include <stdlib.h> +int main() { + char *x = (char*)malloc(10); + 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:9|\[^\n\r]*: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 _*(interceptor_|)free|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output " #1 0x\[0-9a-f\]+ (in _*main (\[^\n\r]*use-after-free-1.c:8|\[^\n\r]*: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 _*(interceptor_|)malloc|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output " #1 0x\[0-9a-f\]+ (in _*main (\[^\n\r]*use-after-free-1.c:7|\[^\n\r]*:0)|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ diff --git a/gcc/testsuite/g++.dg/asan/deep-stack-uaf-1.C b/gcc/testsuite/g++.dg/asan/deep-stack-uaf-1.C new file mode 100644 index 0000000..7677995 --- /dev/null +++ b/gcc/testsuite/g++.dg/asan/deep-stack-uaf-1.C @@ -0,0 +1,39 @@ +// Check that we can store lots of stack frames if asked to. + +// { dg-do run } +// { dg-skip-if "" { *-*-* } { "-flto" } { "" } } +// { dg-set-target-env-var ASAN_OPTIONS "malloc_context_size=120:redzone=512" } +// { dg-options "-fno-omit-frame-pointer -fno-optimize-sibling-calls" } +// { dg-additional-options "-mno-omit-leaf-frame-pointer" { target { i?86-*-* x86_64-*-* } } } +// { dg-shouldfail "asan" } + +#include <stdlib.h> +#include <stdio.h> + +template <int depth> +struct DeepFree { + static void __attribute__((noinline)) + free(char *x) { + DeepFree<depth - 1>::free(x); + } +}; + +template<> +struct DeepFree<0> { + static void __attribute__((noinline)) + 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)" } diff --git a/gcc/testsuite/g++.dg/asan/deep-tail-call-1.C b/gcc/testsuite/g++.dg/asan/deep-tail-call-1.C new file mode 100644 index 0000000..5ac63f1d --- /dev/null +++ b/gcc/testsuite/g++.dg/asan/deep-tail-call-1.C @@ -0,0 +1,22 @@ +// { dg-do run } +// { dg-options "-fno-omit-frame-pointer -fno-optimize-sibling-calls" } +// { dg-additional-options "-mno-omit-leaf-frame-pointer" { target { i?86-*-* x86_64-*-* } } } +// { 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); } +volatile int one = 1; +int main() { + call1(one); + 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)" } diff --git a/gcc/testsuite/g++.dg/asan/deep-thread-stack-1.C b/gcc/testsuite/g++.dg/asan/deep-thread-stack-1.C new file mode 100644 index 0000000..12d8a7a --- /dev/null +++ b/gcc/testsuite/g++.dg/asan/deep-thread-stack-1.C @@ -0,0 +1,56 @@ +// { dg-do run { target pthread } } +// { dg-options "-lasan -lpthread" } +// { 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:" } diff --git a/gcc/testsuite/g++.dg/asan/default-options-1.C b/gcc/testsuite/g++.dg/asan/default-options-1.C new file mode 100644 index 0000000..42b4164 --- /dev/null +++ b/gcc/testsuite/g++.dg/asan/default-options-1.C @@ -0,0 +1,15 @@ +// { dg-do run } + +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)" } diff --git a/gcc/testsuite/g++.dg/asan/dlclose-test-1-so.cc b/gcc/testsuite/g++.dg/asan/dlclose-test-1-so.cc new file mode 100644 index 0000000..99f00e2 --- /dev/null +++ b/gcc/testsuite/g++.dg/asan/dlclose-test-1-so.cc @@ -0,0 +1,32 @@ +//===----------- dlclose-test-so.cc -----------------------------*- C++ -*-===// +// +// 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__); +} diff --git a/gcc/testsuite/g++.dg/asan/interception-failure-test-1.C b/gcc/testsuite/g++.dg/asan/interception-failure-test-1.C new file mode 100644 index 0000000..db105ae --- /dev/null +++ b/gcc/testsuite/g++.dg/asan/interception-failure-test-1.C @@ -0,0 +1,21 @@ +// If user provides his own libc functions, ASan doesn't +// intercept these functions. + +// { dg-do run } +// { dg-options "-fno-builtin-malloc -fno-builtin-free" } + +#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); + free(x); + return (int)strtol(x, 0, 10); +} + +// { dg-output "my_strtol_interceptor" } diff --git a/gcc/testsuite/g++.dg/asan/interception-malloc-test-1.C b/gcc/testsuite/g++.dg/asan/interception-malloc-test-1.C new file mode 100644 index 0000000..b7999e9 --- /dev/null +++ b/gcc/testsuite/g++.dg/asan/interception-malloc-test-1.C @@ -0,0 +1,24 @@ +// ASan interceptor can be accessed with __interceptor_ prefix. + +// { dg-do run { target *-*-linux* } } +// { dg-options "-fno-builtin-free" } +// { 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); + free(x); + return (int)strtol(x, 0, 10); +} + +// { dg-output "malloc call.*(\n|\r\n|\r)" } +// { dg-output "\[^\n\r]*heap-use-after-free" } diff --git a/gcc/testsuite/g++.dg/asan/interception-test-1.C b/gcc/testsuite/g++.dg/asan/interception-test-1.C new file mode 100644 index 0000000..f12f3b6 --- /dev/null +++ b/gcc/testsuite/g++.dg/asan/interception-test-1.C @@ -0,0 +1,23 @@ +// ASan interceptor can be accessed with __interceptor_ prefix. + +// { dg-do run } +// { dg-options "-fno-builtin-malloc -fno-builtin-free" } +// { 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); + 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" } diff --git a/gcc/testsuite/g++.dg/asan/large-func-test-1.C b/gcc/testsuite/g++.dg/asan/large-func-test-1.C new file mode 100644 index 0000000..32981fa --- /dev/null +++ b/gcc/testsuite/g++.dg/asan/large-func-test-1.C @@ -0,0 +1,45 @@ +// { 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]++; +} +volatile int one = 1; +int main() { + int *x = new int[100]; + LargeFunction(x, one - 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|\[^\n\r]*: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|_*_Znw\[mj\])|\[(\])\[^\n\r]*(\n|\r\n|\r)" } diff --git a/gcc/testsuite/g++.dg/asan/shared-lib-test-1-so.cc b/gcc/testsuite/g++.dg/asan/shared-lib-test-1-so.cc new file mode 100644 index 0000000..7548bc0 --- /dev/null +++ b/gcc/testsuite/g++.dg/asan/shared-lib-test-1-so.cc @@ -0,0 +1,20 @@ +//===----------- shared-lib-test-so.cc --------------------------*- C++ -*-===// +// +// 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]++; +} diff --git a/gcc/testsuite/g++.dg/asan/symbolize-callback-1.C b/gcc/testsuite/g++.dg/asan/symbolize-callback-1.C new file mode 100644 index 0000000..9978958 --- /dev/null +++ b/gcc/testsuite/g++.dg/asan/symbolize-callback-1.C @@ -0,0 +1,21 @@ +// { dg-do run } +// { dg-skip-if "" { *-*-* } { "*" } { "-O2" } } +// { dg-options "-fno-builtin-malloc -fno-builtin-free" } +// { dg-shouldfail "asan" } + +#include <stdio.h> +#include <stdlib.h> + +extern "C" +bool __asan_symbolize(const void *, char *out_buffer, int out_size) { + snprintf(out_buffer, out_size, "MySymbolizer"); + return true; +} + +int main() { + char *x = (char*)malloc(10); + free(x); + return x[5]; +} + +// { dg-output "MySymbolizer" } diff --git a/gcc/testsuite/lib/gcc-dg.exp b/gcc/testsuite/lib/gcc-dg.exp index c939c50..f2161ea 100644 --- a/gcc/testsuite/lib/gcc-dg.exp +++ b/gcc/testsuite/lib/gcc-dg.exp @@ -254,7 +254,21 @@ if { [info procs ${tool}_load] != [list] \ proc ${tool}_load { program args } { global tool global shouldfail + global set_target_env_var + + set saved_target_env_var [list] + if { [info exists set_target_env_var] \ + && [llength $set_target_env_var] != 0 } { + if { [is_remote target] } { + return [list "unsupported" ""] + } + set-target-env-var + } set result [eval [list saved_${tool}_load $program] $args] + if { [info exists set_target_env_var] \ + && [llength $set_target_env_var] != 0 } { + restore-target-env-var + } if { $shouldfail != 0 } { switch [lindex $result 0] { "pass" { set status "fail" } @@ -266,6 +280,42 @@ if { [info procs ${tool}_load] != [list] \ } } +proc dg-set-target-env-var { args } { + global set_target_env_var + if { [llength $args] != 3 } { + error "dg-set-target-env-var: need two arguments" + return + } + lappend set_target_env_var [list [lindex $args 1] [lindex $args 2]] +} + +proc set-target-env-var { } { + global set_target_env_var + upvar 1 saved_target_env_var saved_target_env_var + foreach env_var $set_target_env_var { + set var [lindex $env_var 0] + set value [lindex $env_var 1] + if [info exists env($var)] { + lappend saved_target_env_var [list $var 1 $env($var)] + } else { + lappend saved_target_env_var [list $var 0] + } + setenv $var $value + } +} + +proc restore-target-env-var { } { + upvar 1 saved_target_env_var saved_target_env_var + foreach env_var [lreverse $saved_target_env_var] { + set var [lindex $env_var 0] + if [lindex $env_var 1] { + setenv $var [lindex $env_var 2] + } else { + unsetenv $var + } + } +} + # Utility routines. # @@ -677,6 +727,7 @@ if { [info procs saved-dg-test] == [list] } { global compiler_conditional_xfail_data global shouldfail global testname_with_flags + global set_target_env_var if { [ catch { eval saved-dg-test $args } errmsg ] } { set saved_info $errorInfo @@ -697,6 +748,9 @@ if { [info procs saved-dg-test] == [list] } { set additional_sources "" set additional_prunes "" set shouldfail 0 + if [info exists set_target_env_var] { + unset set_target_env_var + } unset_timeout_vars if [info exists compiler_conditional_xfail_data] { unset compiler_conditional_xfail_data diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp index ef93ad1..75436a6 100644 --- a/gcc/testsuite/lib/target-supports.exp +++ b/gcc/testsuite/lib/target-supports.exp @@ -719,6 +719,26 @@ proc check_effective_target_mmap {} { return [check_function_available "mmap"] } +# Return 1 if the target supports dlopen, 0 otherwise. +proc check_effective_target_dlopen {} { + return [check_function_available "dlopen"] +} + +# Return 1 if the target supports clone, 0 otherwise. +proc check_effective_target_clone {} { + return [check_function_available "clone"] +} + +# Return 1 if the target supports setrlimit, 0 otherwise. +proc check_effective_target_setrlimit {} { + return [check_function_available "setrlimit"] +} + +# Return 1 if the target supports swapcontext, 0 otherwise. +proc check_effective_target_swapcontext {} { + return [check_function_available "swapcontext"] +} + # Return 1 if compilation with -pthread is error-free for trivial # code, 0 otherwise. |