------- Comment #7 from jakub at gcc dot gnu dot org 2007-05-08 19:08 ------- This really is not specific to OpenMP, I believe the following is valid threaded program: #define _XOPEN_SOURCE 600 #include <pthread.h> #include <stdlib.h>
int v; pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER; pthread_barrier_t b; void foo (int x, int y) { int i; for (i = 0; i < 100; i++) { if (i > x) v = y; } } void * tf (void *arg) { pthread_barrier_wait (&b); if (arg == NULL) { pthread_mutex_lock (&m); if (v != 0) abort (); foo (50, 10); pthread_mutex_unlock (&m); pthread_barrier_wait (&b); foo (120, 30); } else { foo (100, 20); pthread_barrier_wait (&b); pthread_mutex_lock (&m); if (v != 10) abort (); foo (80, 40); if (v != 40) abort (); pthread_mutex_unlock (&m); } return NULL; } int main (void) { pthread_t th[2]; pthread_barrier_init (&b, NULL, 2); if (pthread_create (&th[0], NULL, tf, NULL) || pthread_create (&th[1], NULL, tf, (void *) 1L)) return 1; pthread_join (th[0], NULL); pthread_join (th[1], NULL); return 0; } and at -O0 works just fine and has no races in it, it is quite easy to show the shared variable is only ever read or written inside of the critical section. But loop IM creates a race even when there is none in the code originally, if I compile this with -O2 (both 4.1.x and trunk) it will abort after a couple of attempts. That's why I think we should have a generic option that disables optimizations which are safe only in sequential programs (and -fopenmp would imply that option). -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=31862