From 64f3e6385d977319bb2c0919ec9cb6c69fe8ec1b Mon Sep 17 00:00:00 2001 From: Tom Eccles Date: Tue, 17 Jun 2025 10:50:14 +0000 Subject: [PATCH] [flang][OpenMP] Fix goto within SECTION Previously we didn't push any context for SECTION and they are not modelled with differing scopes and so goto detection couldn't tell that GOTOs between two SECTIONs were between constructs rather than just staying inside of the parent SECTIONS construct. Fixes #143231 --- flang/lib/Semantics/resolve-directives.cpp | 18 ++++++++++++++++-- .../Semantics/OpenMP/parallel-sections01.f90 | 2 ++ flang/test/Semantics/OpenMP/sections-goto.f90 | 11 +++++++++++ flang/test/Semantics/OpenMP/sections02.f90 | 2 ++ 4 files changed, 31 insertions(+), 2 deletions(-) create mode 100644 flang/test/Semantics/OpenMP/sections-goto.f90 diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp index b5f8667fe36f2..282660684e78a 100644 --- a/flang/lib/Semantics/resolve-directives.cpp +++ b/flang/lib/Semantics/resolve-directives.cpp @@ -384,6 +384,9 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor { bool Pre(const parser::OpenMPSectionsConstruct &); void Post(const parser::OpenMPSectionsConstruct &) { PopContext(); } + bool Pre(const parser::OpenMPSectionConstruct &); + void Post(const parser::OpenMPSectionConstruct &) { PopContext(); } + bool Pre(const parser::OpenMPCriticalConstruct &critical); void Post(const parser::OpenMPCriticalConstruct &) { PopContext(); } @@ -2003,6 +2006,12 @@ bool OmpAttributeVisitor::Pre(const parser::OpenMPSectionsConstruct &x) { return true; } +bool OmpAttributeVisitor::Pre(const parser::OpenMPSectionConstruct &x) { + PushContext(x.source, llvm::omp::Directive::OMPD_section); + GetContext().withinConstruct = true; + return true; +} + bool OmpAttributeVisitor::Pre(const parser::OpenMPCriticalConstruct &x) { const auto &beginCriticalDir{std::get(x.t)}; const auto &endCriticalDir{std::get(x.t)}; @@ -3024,8 +3033,13 @@ void OmpAttributeVisitor::CheckLabelContext(const parser::CharBlock source, const parser::CharBlock target, std::optional sourceContext, std::optional targetContext) { auto dirContextsSame = [](DirContext &lhs, DirContext &rhs) -> bool { - // Sometimes nested constructs share a scope but are different contexts - return (lhs.scope == rhs.scope) && (lhs.directive == rhs.directive); + // Sometimes nested constructs share a scope but are different contexts. + // The directiveSource comparison is for OmpSection. Sections do not have + // their own scopes and two different sections both have the same directive. + // Their source however is different. This string comparison is unfortunate + // but should only happen for GOTOs inside of SECTION. + return (lhs.scope == rhs.scope) && (lhs.directive == rhs.directive) && + (lhs.directiveSource == rhs.directiveSource); }; unsigned version{context_.langOptions().OpenMPVersion}; if (targetContext && diff --git a/flang/test/Semantics/OpenMP/parallel-sections01.f90 b/flang/test/Semantics/OpenMP/parallel-sections01.f90 index 6c5a053bf49c9..19448258af766 100644 --- a/flang/test/Semantics/OpenMP/parallel-sections01.f90 +++ b/flang/test/Semantics/OpenMP/parallel-sections01.f90 @@ -35,6 +35,8 @@ program OmpConstructSections01 !$omp section print *, "This is a single statement structured block" !$omp section + !ERROR: invalid branch into an OpenMP structured block + !ERROR: invalid branch leaving an OpenMP structured block open (10, file="random-file-name.txt", err=30) !ERROR: invalid branch into an OpenMP structured block !ERROR: invalid branch leaving an OpenMP structured block diff --git a/flang/test/Semantics/OpenMP/sections-goto.f90 b/flang/test/Semantics/OpenMP/sections-goto.f90 new file mode 100644 index 0000000000000..9fa9df9f50b9c --- /dev/null +++ b/flang/test/Semantics/OpenMP/sections-goto.f90 @@ -0,0 +1,11 @@ +! RUN: %python %S/../test_errors.py %s %flang -fopenmp +! Regression test for #143231 + +!$omp sections +! ERROR: invalid branch into an OpenMP structured block +! ERROR: invalid branch leaving an OpenMP structured block +goto 10 +!$omp section +10 print *, "Invalid jump" +!$omp end sections +end diff --git a/flang/test/Semantics/OpenMP/sections02.f90 b/flang/test/Semantics/OpenMP/sections02.f90 index ee29922a72c08..8144b491071d8 100644 --- a/flang/test/Semantics/OpenMP/sections02.f90 +++ b/flang/test/Semantics/OpenMP/sections02.f90 @@ -19,6 +19,8 @@ program OmpConstructSections01 !$omp section print *, "This is a single statement structured block" !$omp section + !ERROR: invalid branch into an OpenMP structured block + !ERROR: invalid branch leaving an OpenMP structured block open (10, file="random-file-name.txt", err=30) !ERROR: invalid branch into an OpenMP structured block !ERROR: invalid branch leaving an OpenMP structured block