atomic_stack.c: New test.
2013-12-05 Max Ostapenko <m.ostapenko@partner.samsung.com> * c-c++-common/tsan/atomic_stack.c: New test. * c-c++-common/tsan/fd_pipe_race.c: New test. * c-c++-common/tsan/free_race.c: New test. * c-c++-common/tsan/mutexset1.c: New test. * c-c++-common/tsan/race_on_barrier.c: New test. * c-c++-common/tsan/sleep_sync.c: New test. * c-c++-common/tsan/thread_leak.c: New test. * c-c++-common/tsan/thread_leak1.c: New test. * c-c++-common/tsan/thread_leak2.c: New test. * c-c++-common/tsan/tiny_race.c: New test. * c-c++-common/tsan/tls_race.c: New test. * c-c++-common/tsan/write_in_reader_lock.c: New test. * lib/tsan-dg.exp: New file. * gcc.dg/tsan/tsan.exp: New file. * g++.dg/tsan/tsan.exp: New file. * g++.dg/dg.exp: Prune tsan subdirectory. From-SVN: r205704
This commit is contained in:
parent
9bbd48d120
commit
8582650466
|
@ -1,3 +1,22 @@
|
|||
2013-12-05 Max Ostapenko <m.ostapenko@partner.samsung.com>
|
||||
|
||||
* c-c++-common/tsan/atomic_stack.c: New test.
|
||||
* c-c++-common/tsan/fd_pipe_race.c: New test.
|
||||
* c-c++-common/tsan/free_race.c: New test.
|
||||
* c-c++-common/tsan/mutexset1.c: New test.
|
||||
* c-c++-common/tsan/race_on_barrier.c: New test.
|
||||
* c-c++-common/tsan/sleep_sync.c: New test.
|
||||
* c-c++-common/tsan/thread_leak.c: New test.
|
||||
* c-c++-common/tsan/thread_leak1.c: New test.
|
||||
* c-c++-common/tsan/thread_leak2.c: New test.
|
||||
* c-c++-common/tsan/tiny_race.c: New test.
|
||||
* c-c++-common/tsan/tls_race.c: New test.
|
||||
* c-c++-common/tsan/write_in_reader_lock.c: New test.
|
||||
* lib/tsan-dg.exp: New file.
|
||||
* gcc.dg/tsan/tsan.exp: New file.
|
||||
* g++.dg/tsan/tsan.exp: New file.
|
||||
* g++.dg/dg.exp: Prune tsan subdirectory.
|
||||
|
||||
2013-12-05 Kirill Yukhin <kirill.yukhin@intel.com>
|
||||
|
||||
* gcc.target/i386/readeflags-1.c: New.
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
/* { dg-do run } */
|
||||
/* { dg-shouldfail "tsan" } */
|
||||
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int Global;
|
||||
|
||||
void *Thread1(void *x) {
|
||||
sleep(1);
|
||||
__atomic_fetch_add(&Global, 1, __ATOMIC_RELAXED);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *Thread2(void *x) {
|
||||
Global++;
|
||||
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)" } */
|
||||
/* { dg-output " Atomic write of size 4.*" } */
|
||||
/* { dg-output " #0 __tsan_atomic32_fetch_add.*" } */
|
||||
/* { dg-output " #1 Thread1.*" } */
|
|
@ -0,0 +1,37 @@
|
|||
/* { dg-do run } */
|
||||
/* { dg-shouldfail "tsan" } */
|
||||
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int fds[2];
|
||||
|
||||
void *Thread1(void *x) {
|
||||
write(fds[1], "a", 1);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *Thread2(void *x) {
|
||||
sleep(1);
|
||||
close(fds[0]);
|
||||
close(fds[1]);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int main() {
|
||||
pipe(fds);
|
||||
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);
|
||||
}
|
||||
|
||||
/* { dg-output "WARNING: ThreadSanitizer: data race.*\n" } */
|
||||
/* { dg-output " Write of size 8.*\n" } */
|
||||
/* { dg-output " #0 close.*\n" } */
|
||||
/* { dg-output " #1 Thread2.*\n" } */
|
||||
/* { dg-output " Previous read of size 8.*\n" } */
|
||||
/* { dg-output " #0 write.*\n" } */
|
||||
/* { dg-output " #1 Thread1.*\n" } */
|
|
@ -0,0 +1,28 @@
|
|||
/* { 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 at.* by main thread:(\n|\r\n|\r)" } */
|
||||
/* { dg-output " #0 bar.*(\n|\r\n|\r)" } */
|
||||
/* { dg-output " #1 main.*(\n|\r\n|\r)" } */
|
||||
/* { dg-output " Previous write of size 8 at.* by main thread:(\n|\r\n|\r)" } */
|
||||
/* { dg-output " #0 free.*(\n|\r\n|\r)" } */
|
||||
/* { dg-output " #\(1|2\) foo.*(\n|\r\n|\r)" } */
|
||||
/* { dg-output " #\(2|3\) main.*(\n|\r\n|\r)" } */
|
|
@ -0,0 +1,41 @@
|
|||
/* { dg-do run } */
|
||||
/* { dg-shouldfail "tsan" } */
|
||||
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int Global;
|
||||
pthread_mutex_t mtx;
|
||||
|
||||
void *Thread1(void *x) {
|
||||
sleep(1);
|
||||
pthread_mutex_lock(&mtx);
|
||||
Global++;
|
||||
pthread_mutex_unlock(&mtx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *Thread2(void *x) {
|
||||
Global--;
|
||||
return NULL;/* { dg-output ".*" } */
|
||||
|
||||
}
|
||||
|
||||
int main() {
|
||||
pthread_mutex_init(&mtx, 0);
|
||||
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 " Read of size 4 at 0x\[0-9a-f\]+ by thread T1 \\(mutexes: write M\[0-9\]\\):.*" } */
|
||||
/* { dg-output " Previous write of size 4 at 0x\[0-9a-f\]+ by thread T2:.*" } */
|
||||
/* { dg-output " Mutex M\[0-9\] created at:.*" } */
|
||||
/* { dg-output " #0 pthread_mutex_init.*" } */
|
||||
/* { dg-output " #1 main (.*mutexset1.c|\\?{2}):\[0-9]+.*" } */
|
|
@ -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) {
|
||||
pthread_barrier_init(&B, 0, 2);
|
||||
pthread_barrier_wait(&B);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *Thread2(void *x) {
|
||||
sleep(1);
|
||||
pthread_barrier_wait(&B);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int main() {
|
||||
pthread_t t;
|
||||
pthread_create(&t, NULL, Thread1, NULL);
|
||||
Thread2(0);
|
||||
pthread_join(t, NULL);
|
||||
pthread_barrier_destroy(&B);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* { dg-output "WARNING: ThreadSanitizer: data race.*(\n|\r\n|\r)" } */
|
|
@ -0,0 +1,31 @@
|
|||
/* { dg-do run } */
|
||||
/* { dg-shouldfail "tsan" } */
|
||||
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int X = 0;
|
||||
|
||||
void MySleep() {
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
void *Thread(void *p) {
|
||||
MySleep(); // Assume the main thread has done the write.
|
||||
X = 42;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main() {
|
||||
pthread_t t;
|
||||
pthread_create(&t, 0, Thread, 0);
|
||||
X = 43;
|
||||
pthread_join(t, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* { dg-output "WARNING: ThreadSanitizer: data race.*(\n|\r\n|\r).*} */
|
||||
/* { dg-output " As if synchronized via sleep:(\n|\r\n|\r)} */
|
||||
/* { dg-output " #0 sleep.*"*} */
|
||||
/* { dg-output " #1 MySleep.*"*} */
|
||||
/* { dg-output " #2 Thread.*"*} */
|
|
@ -0,0 +1,18 @@
|
|||
/* { dg-do run } */
|
||||
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
|
||||
void *Thread(void *x) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main() {
|
||||
pthread_t t;
|
||||
pthread_create(&t, 0, Thread, 0);
|
||||
pthread_join(t, 0);
|
||||
printf("PASS\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* { dg-prune-output "WARNING: ThreadSanitizer: thread leak.*" } */
|
|
@ -0,0 +1,19 @@
|
|||
/* { dg-do run } */
|
||||
/* { dg-shouldfail "tsan" } */
|
||||
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
|
||||
void *Thread(void *x) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main() {
|
||||
pthread_t t;
|
||||
pthread_create(&t, 0, Thread, 0);
|
||||
sleep(1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* { dg-output "WARNING: ThreadSanitizer: thread leak.*(\n|\r\n|\r)" } */
|
||||
/* { dg-output "SUMMARY: ThreadSanitizer: thread leak.*main.*(\n|\r\n|\r)" } */
|
|
@ -0,0 +1,23 @@
|
|||
/* { dg-do run } */
|
||||
/* { dg-shouldfail "tsan" } */
|
||||
/* { dg-skip-if "" { *-*-* } { "-O3 -funroll-loops" "-O3 -funroll-all-loops" } { "" } } */
|
||||
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
|
||||
void *Thread(void *x) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main() {
|
||||
int i;
|
||||
for (i = 0; i < 5; i++) {
|
||||
pthread_t t;
|
||||
pthread_create(&t, 0, Thread, 0);
|
||||
}
|
||||
sleep(1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* { dg-output "WARNING: ThreadSanitizer: thread leak.*(\n|\r\n|\r)" } */
|
||||
/* { dg-output " And 4 more similar thread leaks.*" } */
|
|
@ -0,0 +1,23 @@
|
|||
/* { dg-do run } */
|
||||
/* { dg-shouldfail "tsan" } */
|
||||
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int Global;
|
||||
|
||||
void *Thread1(void *x) {
|
||||
sleep(1);
|
||||
Global = 42;
|
||||
return x;
|
||||
}
|
||||
|
||||
int main() {
|
||||
pthread_t t;
|
||||
pthread_create(&t, 0, Thread1, 0);
|
||||
Global = 43;
|
||||
pthread_join(t, 0);
|
||||
return Global;
|
||||
}
|
||||
|
||||
/* { dg-output "WARNING: ThreadSanitizer: data race.*(\n|\r\n|\r)" } */
|
|
@ -0,0 +1,21 @@
|
|||
/* { dg-do run } */
|
||||
/* { dg-shouldfail "tsan" } */
|
||||
|
||||
#include <pthread.h>
|
||||
#include <stddef.h>
|
||||
|
||||
void *Thread(void *a) {
|
||||
*(int*)a = 43;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main() {
|
||||
static __thread int Var = 42;
|
||||
pthread_t t;
|
||||
pthread_create(&t, 0, Thread, &Var);
|
||||
Var = 43;
|
||||
pthread_join(t, 0);
|
||||
}
|
||||
|
||||
/* { dg-output "WARNING: ThreadSanitizer: data race.*(\n|\r\n|\r).*" } */
|
||||
/* { dg-output " Location is TLS of main thread.(\n|\r\n|\r).*" } */
|
|
@ -0,0 +1,37 @@
|
|||
/* { dg-do run } */
|
||||
/* { dg-shouldfail "tsan" } */
|
||||
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
|
||||
pthread_rwlock_t rwlock;
|
||||
int GLOB;
|
||||
|
||||
void *Thread1(void *p) {
|
||||
(void)p;
|
||||
pthread_rwlock_rdlock(&rwlock);
|
||||
// Write under reader lock.
|
||||
sleep(1);
|
||||
GLOB++;
|
||||
pthread_rwlock_unlock(&rwlock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
pthread_rwlock_init(&rwlock, NULL);
|
||||
pthread_rwlock_rdlock(&rwlock);
|
||||
pthread_t t;
|
||||
pthread_create(&t, 0, Thread1, 0);
|
||||
volatile int x = GLOB;
|
||||
(void)x;
|
||||
pthread_rwlock_unlock(&rwlock);
|
||||
pthread_join(t, 0);
|
||||
pthread_rwlock_destroy(&rwlock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* { dg-output "WARNING: ThreadSanitizer: data race.*(\n|\r\n|\r)" } */
|
||||
/* { dg-output " Write of size 4 at 0x\[0-9a-f\]+ by thread T1.*:(\n|\r\n|\r).*" } */
|
||||
/* { dg-output " #0 Thread1.*\(write_in_reader_lock.c|\\?{2}\):\[0-9\]+ .*" } */
|
||||
/* { dg-output " Previous read of size 4 at.* by main thread.*:(\n|\r\n|\r).*" } */
|
||||
/* { dg-output " #0 main.*\(write_in_reader_lock.c|\\?{2}\):\[0-9\]+.*" } */
|
|
@ -54,6 +54,7 @@ set tests [prune $tests $srcdir/$subdir/guality/*]
|
|||
set tests [prune $tests $srcdir/$subdir/simulate-thread/*]
|
||||
set tests [prune $tests $srcdir/$subdir/asan/*]
|
||||
set tests [prune $tests $srcdir/$subdir/ubsan/*]
|
||||
set tests [prune $tests $srcdir/$subdir/tsan/*]
|
||||
|
||||
# Main loop.
|
||||
g++-dg-runtest $tests $DEFAULT_CXXFLAGS
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
# Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is part of GCC.
|
||||
#
|
||||
# GCC is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# GCC is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# 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 g++-dg.exp
|
||||
load_lib tsan-dg.exp
|
||||
|
||||
if ![check_effective_target_fthread_sanitizer] {
|
||||
return
|
||||
}
|
||||
|
||||
# Initialize `dg'.
|
||||
dg-init
|
||||
if [tsan_init] {
|
||||
|
||||
# Main loop.
|
||||
gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c $srcdir/c-c++-common/tsan/*.c]] ""
|
||||
|
||||
}
|
||||
|
||||
# All done.
|
||||
tsan_finish
|
||||
dg-finish
|
|
@ -0,0 +1,40 @@
|
|||
# Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is part of GCC.
|
||||
#
|
||||
# GCC is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# GCC is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# 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 tsan-dg.exp
|
||||
|
||||
if ![check_effective_target_fthread_sanitizer] {
|
||||
return
|
||||
}
|
||||
|
||||
# Initialize `dg'.
|
||||
dg-init
|
||||
if [tsan_init] {
|
||||
|
||||
# Main loop.
|
||||
gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c $srcdir/c-c++-common/tsan/*.c]] ""
|
||||
|
||||
}
|
||||
|
||||
# All done.
|
||||
tsan_finish
|
||||
dg-finish
|
|
@ -0,0 +1,114 @@
|
|||
# Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with GCC; see the file COPYING3. If not see
|
||||
# <http://www.gnu.org/licenses/>.
|
||||
|
||||
# Return 1 if compilation with -fsanitize=thread is error-free for trivial
|
||||
# code, 0 otherwise.
|
||||
|
||||
proc check_effective_target_fthread_sanitizer {} {
|
||||
return [check_no_compiler_messages faddress_sanitizer object {
|
||||
void foo (void) { }
|
||||
} "-fPIE -pie -fsanitize=thread"]
|
||||
}
|
||||
|
||||
#
|
||||
# tsan_link_flags -- compute library path and flags to find libtsan.
|
||||
# (originally from g++.exp)
|
||||
#
|
||||
|
||||
proc tsan_link_flags { paths } {
|
||||
global srcdir
|
||||
global ld_library_path
|
||||
global shlib_ext
|
||||
|
||||
set gccpath ${paths}
|
||||
set flags ""
|
||||
|
||||
set shlib_ext [get_shlib_extension]
|
||||
|
||||
if { $gccpath != "" } {
|
||||
if { [file exists "${gccpath}/libsanitizer/tsan/.libs/libtsan.a"]
|
||||
|| [file exists "${gccpath}/libsanitizer/tsan/.libs/libtsan.${shlib_ext}"] } {
|
||||
append flags " -B${gccpath}/libsanitizer/tsan/ "
|
||||
append flags " -L${gccpath}/libsanitizer/tsan/.libs "
|
||||
append ld_library_path ":${gccpath}/libsanitizer/tsan/.libs"
|
||||
}
|
||||
} else {
|
||||
global tool_root_dir
|
||||
|
||||
set libtsan [lookfor_file ${tool_root_dir} libtsan]
|
||||
if { $libtsan != "" } {
|
||||
append flags "-L${libtsan} "
|
||||
append ld_library_path ":${libtsan}"
|
||||
}
|
||||
}
|
||||
|
||||
set_ld_library_path_env_vars
|
||||
|
||||
return "$flags"
|
||||
}
|
||||
|
||||
#
|
||||
# tsan_init -- called at the start of each subdir of tests
|
||||
#
|
||||
|
||||
proc tsan_init { args } {
|
||||
global TEST_ALWAYS_FLAGS
|
||||
global ALWAYS_CXXFLAGS
|
||||
global TOOL_OPTIONS
|
||||
global tsan_saved_TEST_ALWAYS_FLAGS
|
||||
|
||||
set link_flags ""
|
||||
if ![is_remote host] {
|
||||
if [info exists TOOL_OPTIONS] {
|
||||
set link_flags "[tsan_link_flags [get_multilibs ${TOOL_OPTIONS}]]"
|
||||
} else {
|
||||
set link_flags "[tsan_link_flags [get_multilibs]]"
|
||||
}
|
||||
}
|
||||
|
||||
if [info exists TEST_ALWAYS_FLAGS] {
|
||||
set tsan_saved_TEST_ALWAYS_FLAGS $TEST_ALWAYS_FLAGS
|
||||
}
|
||||
if [info exists ALWAYS_CXXFLAGS] {
|
||||
set ALWAYS_CXXFLAGS [concat "{ldflags=$link_flags}" $ALWAYS_CXXFLAGS]
|
||||
set ALWAYS_CXXFLAGS [concat "{additional_flags=-fPIE -pie -fsanitize=thread -g}" $ALWAYS_CXXFLAGS]
|
||||
} else {
|
||||
if [info exists TEST_ALWAYS_FLAGS] {
|
||||
set TEST_ALWAYS_FLAGS "$link_flags -fPIE -pie -fsanitize=thread -g $TEST_ALWAYS_FLAGS"
|
||||
} else {
|
||||
set TEST_ALWAYS_FLAGS "$link_flags -fPIE -pie -fsanitize=thread -g"
|
||||
}
|
||||
}
|
||||
if { $link_flags != "" } {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
#
|
||||
# tsan_finish -- called at the start of each subdir of tests
|
||||
#
|
||||
|
||||
proc tsan_finish { args } {
|
||||
global TEST_ALWAYS_FLAGS
|
||||
global tsan_saved_TEST_ALWAYS_FLAGS
|
||||
|
||||
if [info exists tsan_saved_TEST_ALWAYS_FLAGS] {
|
||||
set TEST_ALWAYS_FLAGS $tsan_saved_TEST_ALWAYS_FLAGS
|
||||
} else {
|
||||
unset TEST_ALWAYS_FLAGS
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue