Hi! I've adjusted what I could now in check_omp_nesting_restrictions to match the 4.0 draft.
2013-04-30 Jakub Jelinek <ja...@redhat.com> * omp-low.c (check_omp_nesting_restrictions): Diagnose OpenMP constructs nested inside simd region. Don't treat #pragma omp simd as work-sharing region. Disallow work-sharing constructs inside of critical region. Complain if ordered region is nested inside of parallel region without loop region in between. (scan_omp_1_stmt): Call check_omp_nesting_restrictions even for GOMP_{cancel{,lation_point},taskyield,taskwait} calls. * gfortran.dg/gomp/appendix-a/a.35.5.f90: Add dg-error. --- gcc/omp-low.c.jj 2013-04-23 16:15:06.000000000 +0200 +++ gcc/omp-low.c 2013-04-30 10:26:40.402771053 +0200 @@ -1859,9 +1859,21 @@ scan_omp_single (gimple stmt, omp_contex static bool check_omp_nesting_restrictions (gimple stmt, omp_context *ctx) { + if (ctx != NULL + && gimple_code (ctx->stmt) == GIMPLE_OMP_FOR + && (gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_SIMD + || gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_FOR_SIMD)) + { + error_at (gimple_location (stmt), + "OpenMP constructs may not be nested inside simd region"); + return false; + } switch (gimple_code (stmt)) { case GIMPLE_OMP_FOR: + if (gimple_omp_for_kind (stmt) == GF_OMP_FOR_KIND_SIMD) + return true; + /* FALLTHRU */ case GIMPLE_OMP_SECTIONS: case GIMPLE_OMP_SINGLE: case GIMPLE_CALL: @@ -1874,8 +1886,12 @@ check_omp_nesting_restrictions (gimple s case GIMPLE_OMP_ORDERED: case GIMPLE_OMP_MASTER: case GIMPLE_OMP_TASK: + case GIMPLE_OMP_CRITICAL: if (is_gimple_call (stmt)) { + if (DECL_FUNCTION_CODE (gimple_call_fndecl (stmt)) + != BUILT_IN_GOMP_BARRIER) + return true; error_at (gimple_location (stmt), "barrier region may not be closely nested inside " "of work-sharing, critical, ordered, master or " @@ -1932,7 +1948,10 @@ check_omp_nesting_restrictions (gimple s } return true; case GIMPLE_OMP_PARALLEL: - return true; + error_at (gimple_location (stmt), + "ordered region must be closely nested inside " + "a loop region with an ordered clause"); + return false; default: break; } @@ -2029,9 +2048,20 @@ scan_omp_1_stmt (gimple_stmt_iterator *g else if (is_gimple_call (stmt)) { tree fndecl = gimple_call_fndecl (stmt); - if (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL - && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_GOMP_BARRIER) - remove = !check_omp_nesting_restrictions (stmt, ctx); + if (fndecl + && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL) + switch (DECL_FUNCTION_CODE (fndecl)) + { + case BUILT_IN_GOMP_BARRIER: + case BUILT_IN_GOMP_CANCEL: + case BUILT_IN_GOMP_CANCELLATION_POINT: + case BUILT_IN_GOMP_TASKYIELD: + case BUILT_IN_GOMP_TASKWAIT: + remove = !check_omp_nesting_restrictions (stmt, ctx); + break; + default: + break; + } } if (remove) { --- gcc/testsuite/gfortran.dg/gomp/appendix-a/a.35.5.f90.jj 2013-03-20 10:05:25.462181487 +0100 +++ gcc/testsuite/gfortran.dg/gomp/appendix-a/a.35.5.f90 2013-04-30 17:24:27.805425874 +0200 @@ -6,7 +6,7 @@ !$OMP CRITICAL CALL WORK(N,1) ! incorrect nesting of barrier region in a critical region -!$OMP BARRIER +!$OMP BARRIER ! { dg-error "region may not be closely nested inside of" } CALL WORK(N,2) !$OMP END CRITICAL !$OMP END PARALLEL Jakub