1#include <pthread.h> 2#include <stdio.h> 3#include <unistd.h> 4 5int Global; 6 7void __attribute__((noinline)) foo1() { 8 Global = 42; 9} 10 11void __attribute__((noinline)) bar1() { 12 volatile int tmp = 42; 13 int tmp2 = tmp; 14 (void)tmp2; 15 foo1(); 16} 17 18void __attribute__((noinline)) foo2() { 19 volatile int tmp = Global; 20 int tmp2 = tmp; 21 (void)tmp2; 22} 23 24void __attribute__((noinline)) bar2() { 25 volatile int tmp = 42; 26 int tmp2 = tmp; 27 (void)tmp2; 28 foo2(); 29} 30 31void *Thread1(void *x) { 32 usleep(1000000); 33 bar1(); 34 return NULL; 35} 36 37int main() { 38 pthread_t t; 39 pthread_create(&t, NULL, Thread1, NULL); 40 bar2(); 41 pthread_join(t, NULL); 42} 43 44// CHECK: WARNING: ThreadSanitizer: data race 45// CHECK-NEXT: Write of size 4 at {{.*}} by thread 1: 46// CHECK-NEXT: #0 foo1{{.*}} {{.*}}simple_stack2.cc:8{{(:3)?}} ({{.*}}) 47// CHECK-NEXT: #1 bar1{{.*}} {{.*}}simple_stack2.cc:15{{(:3)?}} ({{.*}}) 48// CHECK-NEXT: #2 Thread1{{.*}} {{.*}}simple_stack2.cc:33{{(:3)?}} ({{.*}}) 49// CHECK: Previous read of size 4 at {{.*}} by main thread: 50// CHECK-NEXT: #0 foo2{{.*}} {{.*}}simple_stack2.cc:19{{(:28)?}} ({{.*}}) 51// CHECK-NEXT: #1 bar2{{.*}} {{.*}}simple_stack2.cc:28{{(:3)?}} ({{.*}}) 52// CHECK-NEXT: #2 main{{.*}} {{.*}}simple_stack2.cc:40{{(:3)?}} ({{.*}}) 53