https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102409
Bug ID: 102409 Summary: _pragma ("omp ...") expansion issue - placed in the wrong scope Product: gcc Version: 12.0 Status: UNCONFIRMED Keywords: wrong-code Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: burnus at gcc dot gnu.org Target Milestone: --- Created attachment 51484 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=51484&action=edit Testcase. Compile with "g++ -fopenmp" or with "g++ -E" vs. "clang++ -E" and inspect "omp ordered" placement I have to admit that I do not know the fine print of _Pragma and nested macro expansion. However, the result I get with clang matches what I naively would expect – while I find the result for GCC odd. I also do not know whether this use is an extension or matches the C (C++?) standard. I think it is similar to PR 91669, PR 90400, PR91285, PR 82335 ... except that here only the _Pragma that ends up at the wrong spot is the one which is used in the macro call – while those which are in a #define are handled properly. If I read the other PRs correctly, there the issue is the _Pragma in the macro #define. Nonetheless, they may still fail due to the very same reason. * * * In any case, the result which clang gives matches the expectation of the testcase author of the test at https://github.com/clang-ykt/omptests/blob/master/t-for/test.c#L296 Due to GCC's macro/_Pragma expansion, that one (as well as the attached stripped-down version) fails with: error: ‘ordered’ region may not be closely nested inside of ‘critical’, ‘ordered’, explicit ‘task’ or ‘taskloop’ region * * * The code uses: #define PARALLEL(X) TEST({ \ ... _Pragma("omp for ordered") \ X \ _Pragma("omp for schedule(auto) ordered") \ X \ }) ... PARALLEL( for (int i = 0; i < N; i++) { \ _Pragma("omp ordered") \ EXPECTED: same result as with clang++-11 -E -fopenmp: ... #pragma omp for ordered for (int i = 0; i < (1024*3); i++) { #pragma omp ordered S[0] += C[i] + D[i]; } #pragma omp for schedule(auto) ordered for (int i = 0; i < (1024*3); i++) { #pragma omp ordered S[0] += C[i] + D[i]; } } }} } } } ... BUT: g++ -E -fopenmp gives the following, placing the 'omp ordered' before TEST instead of inside before "S[0] = " together with the rest of X: #pragma omp ordered #pragma omp ordered { int fail = 0, trial; for (int trial = 0; trial < (1) && fail == 0; trial++) { ... #pragma omp for ordered for (int i = 0; i < (1024*3); i++) { S[0] += C[i] + D[i]; } #pragma omp for schedule(auto) ordered for (int i = 0; i < (1024*3); i++) { S[0] += C[i] + D[i]; } } }} } } }