Skip to content

Commit e06363f

Browse files
authored
[flang][OpenMP] Verify uses of OmpCancellationConstructTypeClause (#139743)
Some directive names can be used as clauses, for example in "cancel". In case where a directive name is misplaced, it could be interpreted as a clause. Verify that such uses are valid, and emit a diagnostic message if not. Fixes #138224
1 parent 3abd77a commit e06363f

File tree

3 files changed

+38
-25
lines changed

3 files changed

+38
-25
lines changed

flang/lib/Parser/openmp-parsers.cpp

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -98,10 +98,12 @@ struct OmpDirectiveNameParser {
9898
using Token = TokenStringMatch<false, false>;
9999

100100
std::optional<resultType> Parse(ParseState &state) const {
101+
auto begin{state.GetLocation()};
101102
for (const NameWithId &nid : directives()) {
102103
if (attempt(Token(nid.first.data())).Parse(state)) {
103104
OmpDirectiveName n;
104105
n.v = nid.second;
106+
n.source = parser::CharBlock(begin, state.GetLocation());
105107
return n;
106108
}
107109
}
@@ -1104,18 +1106,8 @@ TYPE_PARSER( //
11041106
"WHEN" >> construct<OmpClause>(construct<OmpClause::When>(
11051107
parenthesized(Parser<OmpWhenClause>{}))) ||
11061108
// Cancellable constructs
1107-
"DO"_id >=
1108-
construct<OmpClause>(construct<OmpClause::CancellationConstructType>(
1109-
Parser<OmpCancellationConstructTypeClause>{})) ||
1110-
"PARALLEL"_id >=
1111-
construct<OmpClause>(construct<OmpClause::CancellationConstructType>(
1112-
Parser<OmpCancellationConstructTypeClause>{})) ||
1113-
"SECTIONS"_id >=
1114-
construct<OmpClause>(construct<OmpClause::CancellationConstructType>(
1115-
Parser<OmpCancellationConstructTypeClause>{})) ||
1116-
"TASKGROUP"_id >=
1117-
construct<OmpClause>(construct<OmpClause::CancellationConstructType>(
1118-
Parser<OmpCancellationConstructTypeClause>{})))
1109+
construct<OmpClause>(construct<OmpClause::CancellationConstructType>(
1110+
Parser<OmpCancellationConstructTypeClause>{})))
11191111

11201112
// [Clause, [Clause], ...]
11211113
TYPE_PARSER(sourced(construct<OmpClauseList>(

flang/lib/Semantics/check-omp-structure.cpp

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2422,20 +2422,30 @@ void OmpStructureChecker::Leave(const parser::OpenMPCriticalConstruct &) {
24222422

24232423
void OmpStructureChecker::Enter(
24242424
const parser::OmpClause::CancellationConstructType &x) {
2425-
// Do not call CheckAllowed/CheckAllowedClause, because in case of an error
2426-
// it will print "CANCELLATION_CONSTRUCT_TYPE" as the clause name instead of
2427-
// the contained construct name.
2425+
llvm::omp::Directive dir{GetContext().directive};
24282426
auto &dirName{std::get<parser::OmpDirectiveName>(x.v.t)};
2429-
switch (dirName.v) {
2430-
case llvm::omp::Directive::OMPD_do:
2431-
case llvm::omp::Directive::OMPD_parallel:
2432-
case llvm::omp::Directive::OMPD_sections:
2433-
case llvm::omp::Directive::OMPD_taskgroup:
2434-
break;
2435-
default:
2436-
context_.Say(dirName.source, "%s is not a cancellable construct"_err_en_US,
2437-
parser::ToUpperCaseLetters(getDirectiveName(dirName.v).str()));
2438-
break;
2427+
2428+
if (dir != llvm::omp::Directive::OMPD_cancel &&
2429+
dir != llvm::omp::Directive::OMPD_cancellation_point) {
2430+
// Do not call CheckAllowed/CheckAllowedClause, because in case of an error
2431+
// it will print "CANCELLATION_CONSTRUCT_TYPE" as the clause name instead
2432+
// of the contained construct name.
2433+
context_.Say(dirName.source, "%s cannot follow %s"_err_en_US,
2434+
parser::ToUpperCaseLetters(getDirectiveName(dirName.v)),
2435+
parser::ToUpperCaseLetters(getDirectiveName(dir)));
2436+
} else {
2437+
switch (dirName.v) {
2438+
case llvm::omp::Directive::OMPD_do:
2439+
case llvm::omp::Directive::OMPD_parallel:
2440+
case llvm::omp::Directive::OMPD_sections:
2441+
case llvm::omp::Directive::OMPD_taskgroup:
2442+
break;
2443+
default:
2444+
context_.Say(dirName.source,
2445+
"%s is not a cancellable construct"_err_en_US,
2446+
parser::ToUpperCaseLetters(getDirectiveName(dirName.v)));
2447+
break;
2448+
}
24392449
}
24402450
}
24412451

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
!RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags
2+
3+
subroutine f(x)
4+
integer :: x
5+
!ERROR: PARALLEL cannot follow SECTIONS
6+
!$omp sections parallel
7+
!$omp section
8+
x = x + 1
9+
!$omp end sections
10+
end
11+
end

0 commit comments

Comments
 (0)