Index: openmp/trunk/runtime/src/kmp_barrier.cpp =================================================================== --- openmp/trunk/runtime/src/kmp_barrier.cpp +++ openmp/trunk/runtime/src/kmp_barrier.cpp @@ -1212,6 +1212,13 @@ team->t.t_bar[bt].b_team_arrived += 1; #endif +#if OMP_40_ENABLED + // Reset cancellation flag for worksharing constructs + if(team->t.t_cancel_request == cancel_loop || + team->t.t_cancel_request == cancel_sections ) { + team->t.t_cancel_request = cancel_noreq; + } +#endif #if USE_ITT_BUILD /* TODO: In case of split reduction barrier, master thread may send acquired event early, before the final summation into the shared variable is done (final summation can be a Index: openmp/trunk/runtime/src/kmp_runtime.cpp =================================================================== --- openmp/trunk/runtime/src/kmp_runtime.cpp +++ openmp/trunk/runtime/src/kmp_runtime.cpp @@ -1372,6 +1372,9 @@ KMP_MB(); } +#if OMP_40_ENABLED + KMP_CHECK_UPDATE(serial_team->t.t_cancel_request, cancel_noreq); +#endif if ( __kmp_env_consistency_check ) __kmp_push_parallel( global_tid, NULL ); Index: openmp/trunk/runtime/test/misc_bugs/cancellation_for_sections.c =================================================================== --- openmp/trunk/runtime/test/misc_bugs/cancellation_for_sections.c +++ openmp/trunk/runtime/test/misc_bugs/cancellation_for_sections.c @@ -0,0 +1,61 @@ +// RUN: %libomp-compile && env OMP_CANCELLATION=true %libomp-run +// Regression test for a bug in cancellation to cover effect of `#pragma omp cancel` +// in a loop construct, on sections construct. +// Pass condition: Cancellation status from `for` does not persist +// to `sections`. + +#include +#include + +int result[2] = {0, 0}; + +void cq416850_for_sections() { + + unsigned i; + // 1) loop + #pragma omp for + for (i = 0; i < 1; i++) { + result[0] = 1; + #pragma omp cancel for + result[0] = 2; + } + +// printf("thread %d: result[0] = %d, result[1] = %d \n", omp_get_thread_num(), result[0], result[1]); + + + // 2) sections + #pragma omp sections + { + #pragma omp section + { + result[1] = 1; + #pragma omp cancellation point sections + result[1] = 2; + } + } +} + +int main(void) { + if(!omp_get_cancellation()) { + printf("Cancellation not enabled!\n"); + return 2; + } + + #pragma omp parallel num_threads(4) + { + cq416850_for_sections(); + } + + if (result[0] != 1 || result[1] != 2) { + printf("Incorrect values. " + "result[0] = %d (expected 1), " + "result[1] = %d (expected 2).\n", + result[0], result[1]); + printf("FAILED\n"); + return 1; + } + + printf("PASSED\n"); + return 0; +} +