diff options
author | chefmax <chefmax@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-12-12 11:44:23 +0000 |
---|---|---|
committer | chefmax <chefmax@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-12-12 11:44:23 +0000 |
commit | 1b67c32f615d2edbe01337e2dffd915ad762b89e (patch) | |
tree | a713197eaeba8ba49842a744edcbbea8b3eef538 /gcc/testsuite | |
parent | c71b5fcbeaeb86e8fa5f7e30b2edac6b11c96e1c (diff) | |
download | gcc-1b67c32f615d2edbe01337e2dffd915ad762b89e.tar.gz |
2013-12-12 Max Ostapenko <m.ostapenko@partner.samsung.com>
* c-c++-common/tsan/free_race2.c: New file.
* c-c++-common/tsan/race_on_barrier2.c: Likewise.
* c-c++-common/tsan/race_on_mutex.c: Likewise.
* c-c++-common/tsan/race_on_mutex2.c: Likewise.
* c-c++-common/tsan/simple_race.c: Likewise.
* c-c++-common/tsan/simple_stack.c: Likewise.
* g++.dg/tsan/aligned_vs_unaligned_race.C: Likewise. Test applies only on x86_64-linux targets.
* g++.dg/tsan/atomic_free.C: Likewise.
* g++.dg/tsan/atomic_free2.C: Likewise.
* g++.dg/tsan/benign_race.C: Likewise.
* g++.dg/tsan/cond_race.C: Likewise.
* g++.dg/tsan/default_options.C: Likewise.
* g++.dg/tsan/fd_close_norace.C: Likewise.
* g++.dg/tsan/fd_close_norace2.C: Likewise.
* g++-dg/tsan/tsan.exp: Modified to run additional C++ tests.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@205925 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/testsuite')
-rw-r--r-- | gcc/testsuite/ChangeLog | 18 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/tsan/free_race2.c | 29 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/tsan/race_on_barrier2.c | 33 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/tsan/race_on_mutex.c | 44 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/tsan/race_on_mutex2.c | 26 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/tsan/simple_race.c | 28 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/tsan/simple_stack.c | 66 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/tsan/aligned_vs_unaligned_race.C | 31 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/tsan/atomic_free.C | 21 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/tsan/atomic_free2.C | 21 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/tsan/benign_race.C | 40 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/tsan/cond_race.C | 37 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/tsan/default_options.C | 34 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/tsan/fd_close_norace.C | 32 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/tsan/fd_close_norace2.C | 31 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/tsan/tsan.exp | 2 |
16 files changed, 492 insertions, 1 deletions
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index b91e83f48bc..bfccb6ab55e 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,21 @@ +2013-12-12 Max Ostapenko <m.ostapenko@partner.samsung.com> + + * c-c++-common/tsan/free_race2.c: New file. + * c-c++-common/tsan/race_on_barrier2.c: Likewise. + * c-c++-common/tsan/race_on_mutex.c: Likewise. + * c-c++-common/tsan/race_on_mutex2.c: Likewise. + * c-c++-common/tsan/simple_race.c: Likewise. + * c-c++-common/tsan/simple_stack.c: Likewise. + * g++.dg/tsan/aligned_vs_unaligned_race.C: Likewise. Test applies only on x86_64-linux targets. + * g++.dg/tsan/atomic_free.C: Likewise. + * g++.dg/tsan/atomic_free2.C: Likewise. + * g++.dg/tsan/benign_race.C: Likewise. + * g++.dg/tsan/cond_race.C: Likewise. + * g++.dg/tsan/default_options.C: Likewise. + * g++.dg/tsan/fd_close_norace.C: Likewise. + * g++.dg/tsan/fd_close_norace2.C: Likewise. + * g++-dg/tsan/tsan.exp: Modified to run additional C++ tests. + 2013-12-12 Jakub Jelinek <jakub@redhat.com> PR libgomp/59467 diff --git a/gcc/testsuite/c-c++-common/tsan/free_race2.c b/gcc/testsuite/c-c++-common/tsan/free_race2.c new file mode 100644 index 00000000000..3c15d2d20f5 --- /dev/null +++ b/gcc/testsuite/c-c++-common/tsan/free_race2.c @@ -0,0 +1,29 @@ +/* { dg-do run } */ +/* { dg-shouldfail "tsan" } */ + +#include <stdlib.h> + +void __attribute__((noinline)) foo(int *mem) { + free(mem); +} + +void __attribute__((noinline)) bar(int *mem) { + mem[0] = 42; +} + +int main() { + int *mem = (int*)malloc(100); + foo(mem); + bar(mem); + return 0; +} + +/* { dg-output "WARNING: ThreadSanitizer: heap-use-after-free.*(\n|\r\n|\r)" } */ +/* { dg-output " Write of size 4.* by main thread:(\n|\r\n|\r)" } */ +/* { dg-output " #0 bar.*" } */ +/* { dg-output " #1 main .*" } */ +/* { dg-output " Previous write of size 8 at .* by main thread:(\n|\r\n|\r)" } */ +/* { dg-output " #0 free .*" } */ +/* { dg-output " #\(1|2\) foo.*(\n|\r\n|\r)" } */ +/* { dg-output " #\(2|3\) main .*" } */ + diff --git a/gcc/testsuite/c-c++-common/tsan/race_on_barrier2.c b/gcc/testsuite/c-c++-common/tsan/race_on_barrier2.c new file mode 100644 index 00000000000..9576c672e1b --- /dev/null +++ b/gcc/testsuite/c-c++-common/tsan/race_on_barrier2.c @@ -0,0 +1,33 @@ +/* { dg-do run } */ +/* { dg-shouldfail "tsan" } */ + +#include <pthread.h> +#include <stdio.h> +#include <stddef.h> +#include <unistd.h> + +pthread_barrier_t B; +int Global; + +void *Thread1(void *x) { + if (pthread_barrier_wait(&B) == PTHREAD_BARRIER_SERIAL_THREAD) + pthread_barrier_destroy(&B); + return NULL; +} + +void *Thread2(void *x) { + if (pthread_barrier_wait(&B) == PTHREAD_BARRIER_SERIAL_THREAD) + pthread_barrier_destroy(&B); + return NULL; +} + +int main() { + pthread_barrier_init(&B, 0, 2); + pthread_t t; + pthread_create(&t, NULL, Thread1, NULL); + Thread2(0); + pthread_join(t, NULL); + return 0; +} + +/* { dg-output "WARNING: ThreadSanitizer: data race.*(\n|\r\n|\r)" } */ diff --git a/gcc/testsuite/c-c++-common/tsan/race_on_mutex.c b/gcc/testsuite/c-c++-common/tsan/race_on_mutex.c new file mode 100644 index 00000000000..f112d097de4 --- /dev/null +++ b/gcc/testsuite/c-c++-common/tsan/race_on_mutex.c @@ -0,0 +1,44 @@ +/* { dg-do run } */ +/* { dg-shouldfail "tsan" } */ + +#include <pthread.h> +#include <stdio.h> +#include <stddef.h> +#include <unistd.h> + +pthread_mutex_t Mtx; +int Global; + +void *Thread1(void *x) { + pthread_mutex_init(&Mtx, 0); + pthread_mutex_lock(&Mtx); + Global = 42; + pthread_mutex_unlock(&Mtx); + return NULL; +} + +void *Thread2(void *x) { + sleep(1); + pthread_mutex_lock(&Mtx); + Global = 43; + pthread_mutex_unlock(&Mtx); + return NULL; +} + +int main() { + pthread_t t[2]; + pthread_create(&t[0], NULL, Thread1, NULL); + pthread_create(&t[1], NULL, Thread2, NULL); + pthread_join(t[0], NULL); + pthread_join(t[1], NULL); + pthread_mutex_destroy(&Mtx); + return 0; +} + +/* { dg-output "WARNING: ThreadSanitizer: data race.*(\n|\r\n|\r)" } */ +/* { dg-output " Atomic read of size 1 at .* by thread T2:(\n|\r\n|\r)" } */ +/* { dg-output " #0 pthread_mutex_lock.*" } */ +/* { dg-output " #1 Thread2.* .*(race_on_mutex.c:22|\\?{2}:0) (.*)" } */ +/* { dg-output " Previous write of size 1 at .* by thread T1:(\n|\r\n|\r)" } */ +/* { dg-output " #0 pthread_mutex_init .* (.)*" } */ +/* { dg-output " #1 Thread1.* .*(race_on_mutex.c:13|\\?{2}:0) .*" } */ diff --git a/gcc/testsuite/c-c++-common/tsan/race_on_mutex2.c b/gcc/testsuite/c-c++-common/tsan/race_on_mutex2.c new file mode 100644 index 00000000000..d8a69801ed0 --- /dev/null +++ b/gcc/testsuite/c-c++-common/tsan/race_on_mutex2.c @@ -0,0 +1,26 @@ +/* { dg-do run } */ +/* { dg-shouldfail "tsan" } */ + +#include <pthread.h> +#include <stdio.h> +#include <stddef.h> +#include <unistd.h> + +void *Thread(void *x) { + pthread_mutex_lock((pthread_mutex_t*)x); + pthread_mutex_unlock((pthread_mutex_t*)x); + return 0; +} + +int main() { + pthread_mutex_t Mtx; + pthread_mutex_init(&Mtx, 0); + pthread_t t; + pthread_create(&t, 0, Thread, &Mtx); + sleep(1); + pthread_mutex_destroy(&Mtx); + pthread_join(t, 0); + return 0; +} + +/* { dg-output "WARNING: ThreadSanitizer: data race.*(\n|\r\n|\r)" } */ diff --git a/gcc/testsuite/c-c++-common/tsan/simple_race.c b/gcc/testsuite/c-c++-common/tsan/simple_race.c new file mode 100644 index 00000000000..24b88e8e5ee --- /dev/null +++ b/gcc/testsuite/c-c++-common/tsan/simple_race.c @@ -0,0 +1,28 @@ +/* { dg-do run } */ +/* { dg-shouldfail "tsan" } */ + +#include <pthread.h> +#include <stdio.h> + +int Global; + +void *Thread1(void *x) { + Global = 42; + return NULL; +} + +void *Thread2(void *x) { + Global = 43; + return NULL; +} + +int main() { + pthread_t t[2]; + pthread_create(&t[0], NULL, Thread1, NULL); + pthread_create(&t[1], NULL, Thread2, NULL); + pthread_join(t[0], NULL); + pthread_join(t[1], NULL); + return 0; +} + +/* { dg-output "WARNING: ThreadSanitizer: data race.*(\n|\r\n|\r)" } */ diff --git a/gcc/testsuite/c-c++-common/tsan/simple_stack.c b/gcc/testsuite/c-c++-common/tsan/simple_stack.c new file mode 100644 index 00000000000..e92d010a59b --- /dev/null +++ b/gcc/testsuite/c-c++-common/tsan/simple_stack.c @@ -0,0 +1,66 @@ +/* { dg-do run } */ +/* { dg-shouldfail "tsan" } */ + +#include <pthread.h> +#include <stdio.h> +#include <unistd.h> + +int Global; + +void __attribute__((noinline)) foo1() { + Global = 42; +} + +void __attribute__((noinline)) bar1() { + volatile int tmp = 42; (void)tmp; + foo1(); +} + +void __attribute__((noinline)) foo2() { + volatile int v = Global; (void)v; +} + +void __attribute__((noinline)) bar2() { + volatile int tmp = 42; (void)tmp; + foo2(); +} + +void *Thread1(void *x) { + sleep(1); + bar1(); + return NULL; +} + +void *Thread2(void *x) { + bar2(); + return NULL; +} + +void StartThread(pthread_t *t, void *(*f)(void*)) { + pthread_create(t, NULL, f, NULL); +} + +int main() { + pthread_t t[2]; + StartThread(&t[0], Thread1); + StartThread(&t[1], Thread2); + pthread_join(t[0], NULL); + pthread_join(t[1], NULL); + return 0; +} + +/* { dg-output "WARNING: ThreadSanitizer: data race.*" } */ +/* { dg-output " Write of size 4 at .* by thread T1:(\n|\r\n|\r)" } */ +/* { dg-output " #0 foo1.* .*(simple_stack.c:11|\\?{2}:0) (.*)" } */ +/* { dg-output " #1 bar1.* .*(simple_stack.c:16|\\?{2}:0) (.*)" } */ +/* { dg-output " #2 Thread1.* .*(simple_stack.c:30|\\?{2}:0) (.*)" } */ +/* { dg-output " Previous read of size 4 at .* by thread T2:(\n|\r\n|\r)" } */ +/* { dg-output " #0 foo2.* .*(simple_stack.c:20|\\?{2}:0) (.*)" } */ +/* { dg-output " #1 bar2.* .*(simple_stack.c:25|\\?{2}:0) (.*)" } */ +/* { dg-output " #2 Thread2.* .*(simple_stack.c:35|\\?{2}:0) (.*)" } */ +/* { dg-output " Thread T1 \\(tid=.*, running\\) created by main thread at:(\n|\r\n|\r)" } */ +/* { dg-output " #0 pthread_create .* (.*)" } */ +/* { dg-output " #1 StartThread.* .*(simple_stack.c:40|\\?{2}:0) (.*)" } */ +/* { dg-output " Thread T2 (.*) created by main thread at:(\n|\r\n|\r)" } */ +/* { dg-output " #0 pthread_create .* (.*)" } */ +/* { dg-output " #1 StartThread.* .*(simple_stack.c:40|\\?{2}:0) (.*)" } */ diff --git a/gcc/testsuite/g++.dg/tsan/aligned_vs_unaligned_race.C b/gcc/testsuite/g++.dg/tsan/aligned_vs_unaligned_race.C new file mode 100644 index 00000000000..ccac527e1d4 --- /dev/null +++ b/gcc/testsuite/g++.dg/tsan/aligned_vs_unaligned_race.C @@ -0,0 +1,31 @@ +/* { dg-do run { target { x86_64-*-linux* } } } */ + +#include <pthread.h> +#include <stdio.h> +#include <stdint.h> + +uint64_t Global[2]; + +void *Thread1(void *x) { + Global[1]++; + return NULL; +} + +void *Thread2(void *x) { + char *p1 = reinterpret_cast<char *>(&Global[0]); + uint64_t *p4 = reinterpret_cast<uint64_t *>(p1 + 1); + (*p4)++; + return NULL; +} + +int main() { + pthread_t t[2]; + pthread_create(&t[0], NULL, Thread1, NULL); + pthread_create(&t[1], NULL, Thread2, NULL); + pthread_join(t[0], NULL); + pthread_join(t[1], NULL); + printf("Pass\n"); + /* { dg-prune-output "ThreadSanitizer: data race.*(\n|\r\n|\r)" } */ + /* { dg-output "Pass.*" } */ + return 0; +} diff --git a/gcc/testsuite/g++.dg/tsan/atomic_free.C b/gcc/testsuite/g++.dg/tsan/atomic_free.C new file mode 100644 index 00000000000..afaad777de6 --- /dev/null +++ b/gcc/testsuite/g++.dg/tsan/atomic_free.C @@ -0,0 +1,21 @@ +/* { dg-do run } */ +/* { dg-shouldfail "tsan" } */ + +#include <pthread.h> +#include <unistd.h> + +void *Thread(void *a) { + __atomic_fetch_add((int*)a, 1, __ATOMIC_SEQ_CST); + return 0; +} + +int main() { + int *a = new int(0); + pthread_t t; + pthread_create(&t, 0, Thread, a); + sleep(1); + delete a; + pthread_join(t, 0); +} + +/* { dg-output "WARNING: ThreadSanitizer: data race.*(\n|\r\n|\r)" } */ diff --git a/gcc/testsuite/g++.dg/tsan/atomic_free2.C b/gcc/testsuite/g++.dg/tsan/atomic_free2.C new file mode 100644 index 00000000000..7ccaa1a95d9 --- /dev/null +++ b/gcc/testsuite/g++.dg/tsan/atomic_free2.C @@ -0,0 +1,21 @@ +/* { dg-do run } */ +/* { dg-shouldfail "tsan" } */ + +#include <pthread.h> +#include <unistd.h> + +void *Thread(void *a) { + sleep(1); + __atomic_fetch_add((int*)a, 1, __ATOMIC_SEQ_CST); + return 0; +} + +int main() { + int *a = new int(0); + pthread_t t; + pthread_create(&t, 0, Thread, a); + delete a; + pthread_join(t, 0); +} + +/* { dg-output "WARNING: ThreadSanitizer: heap-use-after-free.*(\n|\r\n|\r)" } */ diff --git a/gcc/testsuite/g++.dg/tsan/benign_race.C b/gcc/testsuite/g++.dg/tsan/benign_race.C new file mode 100644 index 00000000000..d67b31b2805 --- /dev/null +++ b/gcc/testsuite/g++.dg/tsan/benign_race.C @@ -0,0 +1,40 @@ +/* { dg-do run } */ + +#include <pthread.h> +#include <stdio.h> +#include <unistd.h> + +int Global; +int WTFGlobal; + +extern "C" { +void AnnotateBenignRaceSized(const char *f, int l, + void *mem, unsigned int size, const char *desc); +void WTFAnnotateBenignRaceSized(const char *f, int l, + void *mem, unsigned int size, + const char *desc); +} + + +void *Thread(void *x) { + Global = 42; + WTFGlobal = 142; + return 0; +} + +int main() { + AnnotateBenignRaceSized(__FILE__, __LINE__, + &Global, sizeof(Global), "Race on Global"); + WTFAnnotateBenignRaceSized(__FILE__, __LINE__, + &WTFGlobal, sizeof(WTFGlobal), + "Race on WTFGlobal"); + pthread_t t; + pthread_create(&t, 0, Thread, 0); + sleep(1); + Global = 43; + WTFGlobal = 143; + pthread_join(t, 0); + printf("OK\n"); +} + +/* { dg-prune-output "WARNING: ThreadSanitizer: data race.*(\n|\r\n|\r)" } */ diff --git a/gcc/testsuite/g++.dg/tsan/cond_race.C b/gcc/testsuite/g++.dg/tsan/cond_race.C new file mode 100644 index 00000000000..d28912f2023 --- /dev/null +++ b/gcc/testsuite/g++.dg/tsan/cond_race.C @@ -0,0 +1,37 @@ +/* { dg-do run } */ +/* { dg-shouldfail "tsan" } */ +/* { dg-output "ThreadSanitizer: data race.*" } */ +/* { dg-output "pthread_cond_signal.*" } */ + +#include <stdio.h> +#include <stdlib.h> +#include <pthread.h> + +struct Ctx { + pthread_mutex_t m; + pthread_cond_t c; + bool done; +}; + +void *thr(void *p) { + Ctx *c = (Ctx*)p; + pthread_mutex_lock(&c->m); + c->done = true; + pthread_mutex_unlock(&c->m); + pthread_cond_signal(&c->c); + return 0; +} + +int main() { + Ctx *c = new Ctx(); + pthread_mutex_init(&c->m, 0); + pthread_cond_init(&c->c, 0); + pthread_t th; + pthread_create(&th, 0, thr, c); + pthread_mutex_lock(&c->m); + while (!c->done) + pthread_cond_wait(&c->c, &c->m); + pthread_mutex_unlock(&c->m); + delete c; + pthread_join(th, 0); +} diff --git a/gcc/testsuite/g++.dg/tsan/default_options.C b/gcc/testsuite/g++.dg/tsan/default_options.C new file mode 100644 index 00000000000..b688abff4a9 --- /dev/null +++ b/gcc/testsuite/g++.dg/tsan/default_options.C @@ -0,0 +1,34 @@ +/* { dg-do run } */ +/* { dg-shouldfail "tsan" } */ + +#include <pthread.h> +#include <stdio.h> + +extern "C" const char *__tsan_default_options() { + return "report_bugs=0"; +} + +int Global; + +void *Thread1(void *x) { + Global = 42; + return NULL; +} + +void *Thread2(void *x) { + Global = 43; + return NULL; +} + +int main() { + pthread_t t[2]; + pthread_create(&t[0], NULL, Thread1, NULL); + pthread_create(&t[1], NULL, Thread2, NULL); + pthread_join(t[0], NULL); + pthread_join(t[1], NULL); + fprintf(stderr, "DONE\n"); + return 0; +} + +/* { dg-prune-output "WARNING: ThreadSanitizer: data race.*(\n|\r\n|\r)" } */ +/* { dg-output "DONE" } */ diff --git a/gcc/testsuite/g++.dg/tsan/fd_close_norace.C b/gcc/testsuite/g++.dg/tsan/fd_close_norace.C new file mode 100644 index 00000000000..a31428a3456 --- /dev/null +++ b/gcc/testsuite/g++.dg/tsan/fd_close_norace.C @@ -0,0 +1,32 @@ +/* { dg-do run } */ + +#include <pthread.h> +#include <stdio.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> + +void *Thread1(void *x) { + int f = open("/dev/random", O_RDONLY); + close(f); + return NULL; +} + +void *Thread2(void *x) { + sleep(1); + int f = open("/dev/random", O_RDONLY); + close(f); + return NULL; +} + +int main() { + pthread_t t[2]; + pthread_create(&t[0], NULL, Thread1, NULL); + pthread_create(&t[1], NULL, Thread2, NULL); + pthread_join(t[0], NULL); + pthread_join(t[1], NULL); + printf("OK\n"); +} + +/* { dg-prune-output "WARNING: ThreadSanitizer: data race.*(\n|\r\n|\r)" } */ diff --git a/gcc/testsuite/g++.dg/tsan/fd_close_norace2.C b/gcc/testsuite/g++.dg/tsan/fd_close_norace2.C new file mode 100644 index 00000000000..f2d394c2896 --- /dev/null +++ b/gcc/testsuite/g++.dg/tsan/fd_close_norace2.C @@ -0,0 +1,31 @@ +/* { dg-do run } */ + +#include <pthread.h> +#include <stdio.h> +#include <unistd.h> + +int pipes[2]; + +void *Thread(void *x) { + // wait for shutown signal + while (read(pipes[0], &x, 1) != 1) { + } + close(pipes[0]); + close(pipes[1]); + return 0; +} + +int main() { + if (pipe(pipes)) + return 1; + pthread_t t; + pthread_create(&t, 0, Thread, 0); + // send shutdown signal + while (write(pipes[1], &t, 1) != 1) { + } + pthread_join(t, 0); + printf("OK\n"); +} + +/* { dg-prune-output "WARNING: ThreadSanitizer: data race.*(\n|\r\n|\r)" } */ +/* { dg-output "OK" } */ diff --git a/gcc/testsuite/g++.dg/tsan/tsan.exp b/gcc/testsuite/g++.dg/tsan/tsan.exp index 40c28ce3b91..9bcf6cc8a1d 100644 --- a/gcc/testsuite/g++.dg/tsan/tsan.exp +++ b/gcc/testsuite/g++.dg/tsan/tsan.exp @@ -37,7 +37,7 @@ set-torture-options [list \ if [tsan_init] { # Main loop. -gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c $srcdir/c-c++-common/tsan/*.c]] "" +gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.C $srcdir/c-c++-common/tsan/*.c]] "" } |