https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91517
Bug ID: 91517 Summary: Pragma expansion in variadic macro reorders pragmas and breaks code Product: gcc Version: 9.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: preprocessor Assignee: unassigned at gcc dot gnu.org Reporter: paboyle at ph dot ed.ac.uk Target Milestone: --- Pragma expansion in variadic macro reorders pragmas and breaks code Simple test code #define DO_PRAGMA(x) DO_PRAGMA_(x) #define DO_PRAGMA_(x) _Pragma (#x) #define thread_for( i, num, ... ) DO_PRAGMA(omp parallel for schedule(static)) for ( uint64_t i=0;i<num;i++) { __VA_ARGS__ } ; #define thread_critical DO_PRAGMA(omp critical); thread_for(i,N,{ int x=i; thread_critical { sum+=x; } }); Expands incorrectly to: Peters-Laptop:build peterboyle$ g++-9 -E tmp.cc | uniq # 1 "tmp.cc" # 1 "<built-in>" # 1 "<command-line>" # 1 "tmp.cc" #pragma omp critical # 8 "tmp.cc" #pragma omp parallel for schedule(static) # 8 "tmp.cc" for ( uint64_t i=0;i<N;i++) { { int x=i; ; { sum+=x; } } } ; With Critical pragma in WRONG place. Clang++ and icpc produce right ordering: # 1 "tmp.cc" # 1 "<built-in>" 1 # 1 "<built-in>" 3 # 374 "<built-in>" 3 # 1 "<command line>" 1 # 1 "<built-in>" 2 # 1 "tmp.cc" 2 #pragma omp parallel for schedule(static) # 8 "tmp.cc" for ( uint64_t i=0;i<N;i++) { { int x=i; # 8 "tmp.cc" #pragma omp critical # 8 "tmp.cc" ; { sum+=x; }} } ;;