[flang-commits] [flang] a2ec5c6 - [flang][OpenMP] More detailed checks for argument list items in clauses (#201334)
via flang-commits
flang-commits at lists.llvm.org
Tue Jun 9 08:11:29 PDT 2026
Author: Krzysztof Parzyszek
Date: 2026-06-09T10:11:24-05:00
New Revision: a2ec5c68ba8767c5dc1266946663c8715389da66
URL: https://github.com/llvm/llvm-project/commit/a2ec5c68ba8767c5dc1266946663c8715389da66
DIFF: https://github.com/llvm/llvm-project/commit/a2ec5c68ba8767c5dc1266946663c8715389da66.diff
LOG: [flang][OpenMP] More detailed checks for argument list items in clauses (#201334)
For clauses that take list of variable, locator, and extended list
items, perform checks that the actual arguments meet the corresponding
requirements. This is version-based, since clause requirements have
changed over time.
Added:
Modified:
flang/include/flang/Semantics/openmp-utils.h
flang/lib/Semantics/check-omp-structure.cpp
flang/lib/Semantics/check-omp-structure.h
flang/lib/Semantics/openmp-utils.cpp
flang/test/Semantics/OpenMP/copyprivate04.f90
flang/test/Semantics/OpenMP/copyprivate05.f90
flang/test/Semantics/OpenMP/declare-target01.f90
flang/test/Semantics/OpenMP/from-clause-v45.f90
flang/test/Semantics/OpenMP/from-clause-v51.f90
flang/test/Semantics/OpenMP/in-reduction.f90
flang/test/Semantics/OpenMP/lastprivate01.f90
flang/test/Semantics/OpenMP/name-conflict.f90
flang/test/Semantics/OpenMP/named-constants.f90
flang/test/Semantics/OpenMP/reduction04.f90
flang/test/Semantics/OpenMP/reduction16.f90
flang/test/Semantics/OpenMP/task-reduction.f90
flang/test/Semantics/OpenMP/to-clause-v45.f90
flang/test/Semantics/OpenMP/to-clause-v51.f90
Removed:
################################################################################
diff --git a/flang/include/flang/Semantics/openmp-utils.h b/flang/include/flang/Semantics/openmp-utils.h
index 1ef8f9616ce64..7d7aa788e3f4d 100644
--- a/flang/include/flang/Semantics/openmp-utils.h
+++ b/flang/include/flang/Semantics/openmp-utils.h
@@ -97,12 +97,20 @@ bool IsCommonBlock(const Symbol &sym);
bool IsExtendedListItem(const Symbol &sym);
bool IsVariableListItem(const Symbol &sym);
bool IsTypeParamInquiry(const Symbol &sym);
+bool IsComplexPart(const Symbol &sym);
bool IsStructureComponent(const Symbol &sym);
bool IsPrivatizable(const Symbol &sym);
bool IsVarOrFunctionRef(const MaybeExpr &expr);
bool IsWholeAssumedSizeArray(const parser::OmpObject &object);
+bool IsExtendedListItem(
+ const parser::OmpObject &object, SemanticsContext *semaCtx);
+bool IsLocatorListItem(
+ const parser::OmpObject &object, SemanticsContext *semaCtx);
+bool IsVariableListItem(
+ const parser::OmpObject &object, SemanticsContext *semaCtx);
+
const Symbol *GetHostSymbol(const Symbol &sym);
bool IsMapEnteringType(parser::OmpMapType::Value type);
@@ -161,6 +169,23 @@ bool IsPointerAssignment(const evaluate::Assignment &x);
MaybeExpr MakeEvaluateExpr(const parser::OmpStylizedInstance &inp);
+enum struct ListItemKind : uint32_t {
+ Depend,
+ DirectiveName,
+ DirectiveSpecification,
+ Extended,
+ IntegerExpression,
+ Interop,
+ Locator,
+ Operation,
+ Parameter,
+ ProcedureArgument,
+ Variable,
+};
+
+std::optional<ListItemKind> GetArgumentListItemKind(
+ llvm::omp::Clause clause, unsigned version);
+
bool IsLoopTransforming(llvm::omp::Directive dir);
bool HasDataEnvironment(llvm::omp::Directive dir);
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index b6d64475c6c77..ea15d199192e7 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -424,12 +424,6 @@ void OmpStructureChecker::AnalyzeObject(const parser::OmpObject &object) {
object.u);
}
-void OmpStructureChecker::AnalyzeObjects(const parser::OmpObjectList &objects) {
- for (const parser::OmpObject &object : objects.v) {
- AnalyzeObject(object);
- }
-}
-
const parser::OpenMPConstruct *
OmpStructureChecker::GetCurrentConstruct() const {
for (const LoopOrConstruct &c : llvm::reverse(constructStack_)) {
@@ -622,12 +616,119 @@ bool OmpStructureChecker::HasRequires(llvm::omp::Clause req) {
DEREF(unit.symbol()).details());
}
-void OmpStructureChecker::CheckVariableListItem(
- const SymbolSourceMap &symbols) {
- for (auto &[symbol, source] : symbols) {
- if (!IsVariableListItem(*symbol)) {
- context_.SayWithDecl(
- *symbol, source, "'%s' must be a variable"_err_en_US, symbol->name());
+void OmpStructureChecker::CheckArgumentObjectKind(const parser::OmpClause &x) {
+ unsigned version{context_.langOptions().OpenMPVersion};
+ llvm::omp::Directive dirId{GetContext().directive};
+ llvm::omp::Clause clauseId{x.Id()};
+
+ // Filter out clauses that don't take OmpObjectList.
+ auto argType{GetArgumentListItemKind(clauseId, version)};
+ if (!argType) {
+ return;
+ }
+ switch (*argType) {
+ case ListItemKind::Extended:
+ case ListItemKind::Locator:
+ case ListItemKind::Variable:
+ break;
+ default:
+ return;
+ }
+
+ // Corner cases:
+ if (clauseId == llvm::omp::Clause::OMPC_to) {
+ // 4.5 5+
+ // TO (declare target) extended extended
+ // TO (target update) variable locator
+ if (dirId == llvm::omp::Directive::OMPD_declare_target) {
+ argType = ListItemKind::Extended;
+ } else {
+ assert(dirId == llvm::omp::Directive::OMPD_target_update &&
+ "Unexpected directive");
+ argType = version < 50 ? ListItemKind::Variable : ListItemKind::Locator;
+ }
+ } else if (clauseId == llvm::omp::Clause::OMPC_uniform) {
+ // 4.5 5+
+ // UNIFORM variable parameter
+ // The uniform clause takes std::list<Name> at the moment and cannot
+ // be verified here.
+ return;
+ } else if (clauseId == llvm::omp::Clause::OMPC_depend) {
+ // 6.0- 6.1+
+ // DEPEND locator/doacross depend
+ if (version >= 61) {
+ return;
+ }
+ // The DEPEND clause with SINK/SOURCE will not have an object list.
+ if (auto *depend{parser::Unwrap<parser::OmpDependClause>(x)}) {
+ if (parser::Unwrap<parser::OmpDoacross>(*depend)) {
+ return;
+ }
+ }
+ }
+
+ // Named constants are OK to be used within 'shared' and 'firstprivate'
+ // clauses. The check for this happens a few lines below.
+ bool NamedConstantAllowed{false};
+ switch (clauseId) {
+ case llvm::omp::Clause::OMPC_shared:
+ case llvm::omp::Clause::OMPC_firstprivate:
+ NamedConstantAllowed = true;
+ break;
+ default:
+ break;
+ }
+
+ for (auto &object : DEREF(GetOmpObjectList(x)).v) {
+ AnalyzeObject(object);
+ // substring
+ const Symbol *symbol{GetObjectSymbol(object, /*ultimate=*/true)};
+ if (symbol == nullptr) {
+ // This may happen with a blank common block. Skip these cases.
+ continue;
+ }
+ auto source{*parser::omp::GetObjectSource(object)};
+ if (NamedConstantAllowed && IsNamedConstant(*symbol)) {
+ continue;
+ }
+ // Emit a more user-friendly diagnostic than "'kind' must be a variable
+ // list item" for x%kind, or for cplx%re.
+ if (IsTypeParamInquiry(*symbol)) {
+ context_.Say(source,
+ "Type parameter inquiry is not allowed as a list item on %s clause"_err_en_US,
+ parser::omp::GetUpperName(clauseId, version));
+ continue;
+ }
+ if (IsComplexPart(*symbol)) {
+ // We have been tolerating complex part designators.
+ continue;
+ }
+
+ const char *neededType{nullptr};
+
+ switch (*argType) {
+ case ListItemKind::Extended:
+ if (!IsExtendedListItem(object, &context_)) {
+ neededType = "an extended";
+ }
+ break;
+ case ListItemKind::Locator:
+ if (!IsLocatorListItem(object, &context_)) {
+ neededType = "a locator";
+ }
+ break;
+ case ListItemKind::Variable:
+ if (!IsVariableListItem(object, &context_)) {
+ neededType = "a variable";
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (neededType) {
+ context_.SayWithDecl(*symbol, source,
+ "'%s' must be %s list item"_err_en_US, symbol->name(), neededType);
}
}
}
@@ -2383,7 +2484,6 @@ void OmpStructureChecker::Leave(const parser::OmpDeclareTargetDirective &x) {
std::is_same_v<TypeC, parser::OmpClause::To>) {
auto &objList{*GetOmpObjectList(c)};
CheckSymbolNames(dirName.source, objList);
- CheckTypeParamInquiry(dirName.source, objList);
CheckVarIsNotPartOfAnotherVar(dirName.source, objList);
CheckThreadprivateOrDeclareTargetVar(objList);
}
@@ -3625,44 +3725,7 @@ void OmpStructureChecker::Leave(const parser::OmpClauseList &x) {
void OmpStructureChecker::Enter(const parser::OmpClause &x) {
SetContextClause(x);
-
- llvm::omp::Clause id{x.Id()};
- // The visitors for these clauses do their own checks.
- switch (id) {
- case llvm::omp::Clause::OMPC_copyprivate:
- case llvm::omp::Clause::OMPC_enter:
- case llvm::omp::Clause::OMPC_lastprivate:
- case llvm::omp::Clause::OMPC_reduction:
- case llvm::omp::Clause::OMPC_to:
- return;
- default:
- break;
- }
-
- // Named constants are OK to be used within 'shared' and 'firstprivate'
- // clauses. The check for this happens a few lines below.
- bool SharedOrFirstprivate = false;
- switch (id) {
- case llvm::omp::Clause::OMPC_shared:
- case llvm::omp::Clause::OMPC_firstprivate:
- SharedOrFirstprivate = true;
- break;
- default:
- break;
- }
-
- if (const parser::OmpObjectList *objList{GetOmpObjectList(x)}) {
- AnalyzeObjects(*objList);
- SymbolSourceMap symbols;
- GetSymbolsInObjectList(*objList, symbols);
- for (const auto &[symbol, source] : symbols) {
- if (!IsVariableListItem(*symbol) &&
- !(IsNamedConstant(*symbol) && SharedOrFirstprivate)) {
- context_.SayWithDecl(*symbol, source,
- "'%s' must be a variable"_err_en_US, symbol->name());
- }
- }
- }
+ CheckArgumentObjectKind(x);
}
// Restrictions specific to each clause are implemented apart from the
@@ -3882,17 +3945,6 @@ void OmpStructureChecker::CheckReductionObjects(
}
}
}
- // Type parameter inquiries are not allowed.
- for (const parser::OmpObject &object : objects.v) {
- if (auto *symbol{GetObjectSymbol(object)}) {
- if (IsTypeParamInquiry(*symbol)) {
- auto source{GetObjectSource(object)};
- context_.Say(source ? *source : GetContext().clauseSource,
- "Type parameter inquiry is not permitted in %s clause"_err_en_US,
- parser::omp::GetUpperName(clauseId, version));
- }
- }
- }
}
}
@@ -4174,15 +4226,14 @@ void OmpStructureChecker::CheckSharedBindingInOuterContext(
void OmpStructureChecker::Enter(const parser::OmpClause::Shared &x) {
CheckAllowedClause(llvm::omp::Clause::OMPC_shared);
- CheckTypeParamInquiry(GetContext().clauseSource, x.v);
CheckVarIsNotPartOfAnotherVar(GetContext().clauseSource, x.v, "SHARED");
CheckCrayPointee(x.v, "SHARED");
}
+
void OmpStructureChecker::Enter(const parser::OmpClause::Private &x) {
SymbolSourceMap symbols;
GetSymbolsInObjectList(x.v, symbols);
CheckAllowedClause(llvm::omp::Clause::OMPC_private);
- CheckTypeParamInquiry(GetContext().clauseSource, x.v);
CheckVarIsNotPartOfAnotherVar(GetContext().clauseSource, x.v, "PRIVATE");
CheckIntentInPointer(symbols, llvm::omp::Clause::OMPC_private);
CheckCrayPointee(x.v, "PRIVATE");
@@ -4231,7 +4282,8 @@ void OmpStructureChecker::CheckVarIsNotPartOfAnotherVar(
}
if (report || parser::Unwrap<parser::ArrayElement>(object)) {
- if (llvm::omp::nonPartialVarSet.test(GetContext().directive)) {
+ if (clause.empty() &&
+ llvm::omp::nonPartialVarSet.test(GetContext().directive)) {
context_.Say(source,
"A variable that is part of another variable (as an array or structure element) cannot appear on the %s directive"_err_en_US,
ContextDirectiveAsFortran());
@@ -4246,7 +4298,6 @@ void OmpStructureChecker::CheckVarIsNotPartOfAnotherVar(
void OmpStructureChecker::Enter(const parser::OmpClause::Firstprivate &x) {
CheckAllowedClause(llvm::omp::Clause::OMPC_firstprivate);
- CheckTypeParamInquiry(GetContext().clauseSource, x.v);
CheckVarIsNotPartOfAnotherVar(GetContext().clauseSource, x.v, "FIRSTPRIVATE");
CheckCrayPointee(x.v, "FIRSTPRIVATE");
@@ -4451,7 +4502,6 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Detach &x) {
CheckAllowedClause(llvm::omp::Clause::OMPC_detach);
}
- CheckTypeParamInquiry(GetContext().clauseSource, x.v.v);
// OpenMP 5.2: 12.5.2 Detach clause restrictions
if (version >= 52) {
CheckVarIsNotPartOfAnotherVar(GetContext().clauseSource, x.v.v, "DETACH");
@@ -4907,7 +4957,6 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Copyprivate &x) {
CheckAllowedClause(llvm::omp::Clause::OMPC_copyprivate);
SymbolSourceMap symbols;
GetSymbolsInObjectList(x.v, symbols);
- CheckVariableListItem(symbols);
CheckIntentInPointer(symbols, llvm::omp::Clause::OMPC_copyprivate);
CheckCopyingPolymorphicAllocatable(
symbols, llvm::omp::Clause::OMPC_copyprivate);
@@ -4917,7 +4966,6 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Lastprivate &x) {
CheckAllowedClause(llvm::omp::Clause::OMPC_lastprivate);
const auto &objectList{*GetOmpObjectList(x)};
- CheckTypeParamInquiry(GetContext().clauseSource, objectList);
CheckVarIsNotPartOfAnotherVar(
GetContext().clauseSource, objectList, "LASTPRIVATE");
CheckCrayPointee(objectList, "LASTPRIVATE");
@@ -5159,18 +5207,8 @@ void OmpStructureChecker::Enter(const parser::OmpClause::HasDeviceAddr &x) {
void OmpStructureChecker::Enter(const parser::OmpClause::Enter &x) {
CheckAllowedClause(llvm::omp::Clause::OMPC_enter);
- if (!OmpVerifyModifiers(
- x.v, llvm::omp::OMPC_enter, GetContext().clauseSource, context_)) {
- return;
- }
- SymbolSourceMap symbols;
- GetSymbolsInObjectList(*GetOmpObjectList(x), symbols);
- for (const auto &[symbol, source] : symbols) {
- if (!IsExtendedListItem(*symbol)) {
- context_.SayWithDecl(*symbol, source,
- "'%s' must be a variable or a procedure"_err_en_US, symbol->name());
- }
- }
+ OmpVerifyModifiers(
+ x.v, llvm::omp::OMPC_enter, GetContext().clauseSource, context_);
}
void OmpStructureChecker::Enter(const parser::OmpClause::From &x) {
@@ -5188,10 +5226,6 @@ void OmpStructureChecker::Enter(const parser::OmpClause::From &x) {
}
const auto &objList{*GetOmpObjectList(x)};
- SymbolSourceMap symbols;
- GetSymbolsInObjectList(objList, symbols);
- CheckVariableListItem(symbols);
-
// Ref: [4.5:109:19]
// If a list item is an array section it must specify contiguous storage.
if (version <= 45) {
@@ -5228,10 +5262,6 @@ void OmpStructureChecker::Enter(const parser::OmpClause::To &x) {
}
const auto &objList{*GetOmpObjectList(x)};
- SymbolSourceMap symbols;
- GetSymbolsInObjectList(objList, symbols);
- CheckVariableListItem(symbols);
-
// Ref: [4.5:109:19]
// If a list item is an array section it must specify contiguous storage.
if (version <= 45) {
@@ -5465,6 +5495,9 @@ void OmpStructureChecker::CheckDefinableObjects(
SymbolSourceMap &symbols, const llvm::omp::Clause clause) {
unsigned version{context_.langOptions().OpenMPVersion};
for (auto &[symbol, source] : symbols) {
+ if (!IsVariableListItem(*symbol)) {
+ continue;
+ }
if (auto msg{WhyNotDefinable(source, context_.FindScope(source),
DefinabilityFlags{}, *symbol)}) {
context_
diff --git a/flang/lib/Semantics/check-omp-structure.h b/flang/lib/Semantics/check-omp-structure.h
index 8a85f489eeb4c..fecacf0f891f2 100644
--- a/flang/lib/Semantics/check-omp-structure.h
+++ b/flang/lib/Semantics/check-omp-structure.h
@@ -289,12 +289,11 @@ class OmpStructureChecker : public OmpStructureCheckerBase {
// check-omp-structure.cpp
bool IsAllowedClause(llvm::omp::Clause clauseId);
bool CheckAllowedClause(llvm::omp::Clause clause);
- void CheckVariableListItem(const SymbolSourceMap &symbols);
+ void CheckArgumentObjectKind(const parser::OmpClause &x);
void CheckDirectiveSpelling(
parser::CharBlock spelling, llvm::omp::Directive id);
void CheckDirectiveDeprecation(const parser::OpenMPConstruct &x);
void AnalyzeObject(const parser::OmpObject &object);
- void AnalyzeObjects(const parser::OmpObjectList &objects);
const parser::OpenMPConstruct *GetCurrentConstruct() const;
void CheckSourceLabel(const parser::Label &);
diff --git a/flang/lib/Semantics/openmp-utils.cpp b/flang/lib/Semantics/openmp-utils.cpp
index 633ec2ae45aaa..a747bde8d3346 100644
--- a/flang/lib/Semantics/openmp-utils.cpp
+++ b/flang/lib/Semantics/openmp-utils.cpp
@@ -156,7 +156,8 @@ bool IsCommonBlock(const Symbol &sym) {
}
bool IsVariableListItem(const Symbol &sym) {
- return evaluate::IsVariable(sym) || sym.attrs().test(Attr::POINTER);
+ return evaluate::IsVariable(sym) || IsCommonBlock(sym) ||
+ sym.attrs().test(Attr::POINTER);
}
bool IsExtendedListItem(const Symbol &sym) {
@@ -176,6 +177,14 @@ bool IsTypeParamInquiry(const Symbol &sym) {
sym.details());
}
+bool IsComplexPart(const Symbol &sym) {
+ if (auto *misc{sym.detailsIf<MiscDetails>()}) {
+ return misc->kind() == MiscDetails::Kind::ComplexPartRe ||
+ misc->kind() == MiscDetails::Kind::ComplexPartIm;
+ }
+ return false;
+}
+
bool IsStructureComponent(const Symbol &sym) {
return sym.owner().kind() == Scope::Kind::DerivedType;
}
@@ -219,6 +228,38 @@ bool IsWholeAssumedSizeArray(const parser::OmpObject &object) {
return false;
}
+bool IsExtendedListItem(
+ const parser::OmpObject &object, SemanticsContext *semaCtx) {
+ if (IsVariableListItem(object, semaCtx)) {
+ return true;
+ }
+ if (auto *sym{GetObjectSymbol(object, /*ultimate=*/true)}) {
+ return IsProcedure(*sym);
+ }
+ return false;
+}
+
+bool IsLocatorListItem(
+ const parser::OmpObject &object, SemanticsContext *semaCtx) {
+ if (IsVariableListItem(object, semaCtx)) {
+ return true;
+ }
+ if (auto *desg{parser::Unwrap<parser::Designator>(object)}) {
+ evaluate::ExpressionAnalyzer ea(*semaCtx);
+ auto restorer{ea.GetContextualMessages().DiscardMessages()};
+ return IsVarOrFunctionRef(ea.Analyze(*desg));
+ }
+ return false;
+}
+
+bool IsVariableListItem(
+ const parser::OmpObject &object, SemanticsContext *semaCtx) {
+ if (auto *sym{GetObjectSymbol(object, /*ultimate=*/true)}) {
+ return IsVariableListItem(*sym);
+ }
+ return false;
+}
+
const Symbol *GetHostSymbol(const Symbol &sym) {
if (auto *details{sym.detailsIf<HostAssocDetails>()}) {
return &details->symbol();
@@ -556,6 +597,188 @@ MaybeExpr MakeEvaluateExpr(const parser::OmpStylizedInstance &inp) {
instance.u);
}
+/// For clauses that take argument lists, return the type of the argument
+/// list item. For other clauses return std::nullopt.
+std::optional<ListItemKind> GetArgumentListItemKind(
+ llvm::omp::Clause clause, unsigned version) {
+ switch (clause) {
+ case llvm::omp::Clause::OMPC_absent:
+ if (version >= 51) {
+ return ListItemKind::DirectiveName;
+ }
+ break;
+ case llvm::omp::Clause::OMPC_adjust_args:
+ if (version >= 61) {
+ return ListItemKind::ProcedureArgument;
+ }
+ if (version >= 51) {
+ return ListItemKind::Parameter;
+ }
+ break;
+ case llvm::omp::Clause::OMPC_affinity:
+ if (version >= 50) {
+ return ListItemKind::Locator;
+ }
+ break;
+ case llvm::omp::Clause::OMPC_aligned:
+ return ListItemKind::Variable;
+ case llvm::omp::Clause::OMPC_allocate:
+ if (version >= 50) {
+ return ListItemKind::Variable;
+ }
+ break;
+ case llvm::omp::Clause::OMPC_append_args:
+ if (version >= 51) {
+ return ListItemKind::Operation;
+ }
+ break;
+ case llvm::omp::Clause::OMPC_apply:
+ if (version >= 60) {
+ return ListItemKind::DirectiveSpecification;
+ }
+ break;
+ case llvm::omp::Clause::OMPC_contains:
+ if (version >= 51) {
+ return ListItemKind::DirectiveName;
+ }
+ break;
+ case llvm::omp::Clause::OMPC_copyin:
+ return ListItemKind::Variable;
+ case llvm::omp::Clause::OMPC_copyprivate:
+ return ListItemKind::Variable;
+ case llvm::omp::Clause::OMPC_counts:
+ if (version >= 60) {
+ return ListItemKind::IntegerExpression;
+ }
+ break;
+ case llvm::omp::Clause::OMPC_depend:
+ if (version >= 61) {
+ return ListItemKind::Depend;
+ }
+ if (version >= 50) {
+ return ListItemKind::Locator;
+ }
+ return ListItemKind::Variable;
+ case llvm::omp::Clause::OMPC_enter:
+ if (version >= 52) {
+ return ListItemKind::Extended;
+ }
+ break;
+ case llvm::omp::Clause::OMPC_exclusive:
+ if (version >= 50) {
+ return ListItemKind::Variable;
+ }
+ break;
+ case llvm::omp::Clause::OMPC_firstprivate:
+ return ListItemKind::Variable;
+ case llvm::omp::Clause::OMPC_from:
+ if (version >= 50) {
+ return ListItemKind::Locator;
+ }
+ return ListItemKind::Variable;
+ case llvm::omp::Clause::OMPC_has_device_addr:
+ if (version >= 51) {
+ return ListItemKind::Variable;
+ }
+ break;
+ case llvm::omp::Clause::OMPC_in_reduction:
+ if (version >= 50) {
+ return ListItemKind::Variable;
+ }
+ break;
+ case llvm::omp::Clause::OMPC_inclusive:
+ if (version >= 50) {
+ return ListItemKind::Variable;
+ }
+ break;
+ case llvm::omp::Clause::OMPC_induction:
+ if (version >= 60) {
+ return ListItemKind::Variable;
+ }
+ break;
+ case llvm::omp::Clause::OMPC_interop:
+ if (version >= 60) {
+ return ListItemKind::Interop;
+ }
+ break;
+ case llvm::omp::Clause::OMPC_is_device_ptr:
+ return ListItemKind::Variable;
+ case llvm::omp::Clause::OMPC_lastprivate:
+ return ListItemKind::Variable;
+ case llvm::omp::Clause::OMPC_linear:
+ return ListItemKind::Variable;
+ case llvm::omp::Clause::OMPC_link:
+ return ListItemKind::Variable;
+ case llvm::omp::Clause::OMPC_local:
+ if (version >= 60) {
+ return ListItemKind::Variable;
+ }
+ break;
+ case llvm::omp::Clause::OMPC_map:
+ if (version >= 50) {
+ return ListItemKind::Locator;
+ }
+ return ListItemKind::Variable;
+ case llvm::omp::Clause::OMPC_nontemporal:
+ if (version >= 50) {
+ return ListItemKind::Variable;
+ }
+ break;
+ case llvm::omp::Clause::OMPC_num_threads:
+ if (version >= 60) {
+ return ListItemKind::IntegerExpression;
+ }
+ break;
+ case llvm::omp::Clause::OMPC_permutation:
+ if (version >= 60) {
+ return ListItemKind::IntegerExpression;
+ }
+ break;
+ case llvm::omp::Clause::OMPC_private:
+ return ListItemKind::Variable;
+ case llvm::omp::Clause::OMPC_reduction:
+ return ListItemKind::Variable;
+ case llvm::omp::Clause::OMPC_shared:
+ return ListItemKind::Variable;
+ // TODO 6.1
+ // case llvm::omp::Clause::OMPC_shift:
+ // if (version >= 61) {
+ // return ListItemKind::IntegerExpression;
+ // }
+ // break;
+ case llvm::omp::Clause::OMPC_sizes:
+ if (version >= 51) {
+ return ListItemKind::IntegerExpression;
+ }
+ break;
+ case llvm::omp::Clause::OMPC_task_reduction:
+ if (version >= 50) {
+ return ListItemKind::Variable;
+ }
+ break;
+ case llvm::omp::Clause::OMPC_to:
+ if (version >= 50) {
+ return ListItemKind::Locator;
+ }
+ return ListItemKind::Extended;
+ case llvm::omp::Clause::OMPC_uniform:
+ if (version >= 50) {
+ return ListItemKind::Parameter;
+ }
+ return ListItemKind::Variable;
+ case llvm::omp::Clause::OMPC_use_device_addr:
+ if (version >= 50) {
+ return ListItemKind::Variable;
+ }
+ break;
+ case llvm::omp::Clause::OMPC_use_device_ptr:
+ return ListItemKind::Variable;
+ default:
+ break;
+ }
+ return std::nullopt;
+}
+
bool IsLoopTransforming(llvm::omp::Directive dir) {
switch (dir) {
// TODO case llvm::omp::Directive::OMPD_flatten:
diff --git a/flang/test/Semantics/OpenMP/copyprivate04.f90 b/flang/test/Semantics/OpenMP/copyprivate04.f90
index 8d7800229bc5f..56e37c3a5df1c 100644
--- a/flang/test/Semantics/OpenMP/copyprivate04.f90
+++ b/flang/test/Semantics/OpenMP/copyprivate04.f90
@@ -70,7 +70,7 @@ program omp_copyprivate
! Named constants are shared.
!$omp single
!ERROR: COPYPRIVATE variable 'pi' is not PRIVATE or THREADPRIVATE in outer context
- !ERROR: 'pi' must be a variable
+ !ERROR: 'pi' must be a variable list item
!$omp end single copyprivate(pi)
!$omp parallel do
diff --git a/flang/test/Semantics/OpenMP/copyprivate05.f90 b/flang/test/Semantics/OpenMP/copyprivate05.f90
index 129f8f0b5144e..222628d3e65d9 100644
--- a/flang/test/Semantics/OpenMP/copyprivate05.f90
+++ b/flang/test/Semantics/OpenMP/copyprivate05.f90
@@ -6,7 +6,7 @@ subroutine f00
type t
end type
-!ERROR: 't' must be a variable
+!ERROR: 't' must be a variable list item
!$omp single copyprivate(t)
!$omp end single
end
diff --git a/flang/test/Semantics/OpenMP/declare-target01.f90 b/flang/test/Semantics/OpenMP/declare-target01.f90
index 9bbd66ad5ec43..ddd48c5a96820 100644
--- a/flang/test/Semantics/OpenMP/declare-target01.f90
+++ b/flang/test/Semantics/OpenMP/declare-target01.f90
@@ -75,18 +75,18 @@ module declare_target01
!ERROR: A variable that is part of another variable (as an array or structure element) cannot appear on the DECLARE TARGET directive
!$omp declare target enter (my_var%t_arr)
- !ERROR: A type parameter inquiry cannot appear on the DECLARE TARGET directive
+ !ERROR: Type parameter inquiry is not allowed as a list item on TO clause
!WARNING: The usage of TO clause on DECLARE TARGET directive has been deprecated. Use ENTER clause instead. [-Wopenmp-usage]
!$omp declare target to (my_var%kind_param)
- !ERROR: A type parameter inquiry cannot appear on the DECLARE TARGET directive
+ !ERROR: Type parameter inquiry is not allowed as a list item on ENTER clause
!$omp declare target enter (my_var%kind_param)
- !ERROR: A type parameter inquiry cannot appear on the DECLARE TARGET directive
+ !ERROR: Type parameter inquiry is not allowed as a list item on TO clause
!WARNING: The usage of TO clause on DECLARE TARGET directive has been deprecated. Use ENTER clause instead. [-Wopenmp-usage]
!$omp declare target to (my_var%len_param)
- !ERROR: A type parameter inquiry cannot appear on the DECLARE TARGET directive
+ !ERROR: Type parameter inquiry is not allowed as a list item on ENTER clause
!$omp declare target enter (my_var%len_param)
!WARNING: The usage of TO clause on DECLARE TARGET directive has been deprecated. Use ENTER clause instead. [-Wopenmp-usage]
@@ -113,25 +113,25 @@ module declare_target01
!ERROR: A variable that is part of another variable (as an array or structure element) cannot appear on the DECLARE TARGET directive
!$omp declare target enter (arr(1:2))
- !ERROR: A type parameter inquiry cannot appear on the DECLARE TARGET directive
+ !ERROR: Type parameter inquiry is not allowed as a list item on TO clause
!WARNING: The usage of TO clause on DECLARE TARGET directive has been deprecated. Use ENTER clause instead. [-Wopenmp-usage]
!$omp declare target to (x%KIND)
- !ERROR: A type parameter inquiry cannot appear on the DECLARE TARGET directive
+ !ERROR: Type parameter inquiry is not allowed as a list item on ENTER clause
!$omp declare target enter (x%KIND)
- !ERROR: A type parameter inquiry cannot appear on the DECLARE TARGET directive
+ !ERROR: Type parameter inquiry is not allowed as a list item on TO clause
!WARNING: The usage of TO clause on DECLARE TARGET directive has been deprecated. Use ENTER clause instead. [-Wopenmp-usage]
!$omp declare target to (w%LEN)
- !ERROR: A type parameter inquiry cannot appear on the DECLARE TARGET directive
+ !ERROR: Type parameter inquiry is not allowed as a list item on ENTER clause
!$omp declare target enter (w%LEN)
- !ERROR: A type parameter inquiry cannot appear on the DECLARE TARGET directive
+ !ERROR: Type parameter inquiry is not allowed as a list item on TO clause
!WARNING: The usage of TO clause on DECLARE TARGET directive has been deprecated. Use ENTER clause instead. [-Wopenmp-usage]
!$omp declare target to (y%KIND)
- !ERROR: A type parameter inquiry cannot appear on the DECLARE TARGET directive
+ !ERROR: Type parameter inquiry is not allowed as a list item on ENTER clause
!$omp declare target enter (y%KIND)
!$omp declare target link (my_var2)
@@ -144,10 +144,10 @@ module declare_target01
!ERROR: A variable that is part of another variable (as an array or structure element) cannot appear on the DECLARE TARGET directive
!$omp declare target link (my_var2%t_arr)
- !ERROR: A type parameter inquiry cannot appear on the DECLARE TARGET directive
+ !ERROR: Type parameter inquiry is not allowed as a list item on LINK clause
!$omp declare target link (my_var2%kind_param)
- !ERROR: A type parameter inquiry cannot appear on the DECLARE TARGET directive
+ !ERROR: Type parameter inquiry is not allowed as a list item on LINK clause
!$omp declare target link (my_var2%len_param)
!$omp declare target link (arr2)
@@ -158,12 +158,12 @@ module declare_target01
!ERROR: A variable that is part of another variable (as an array or structure element) cannot appear on the DECLARE TARGET directive
!$omp declare target link (arr2(1:2))
- !ERROR: A type parameter inquiry cannot appear on the DECLARE TARGET directive
+ !ERROR: Type parameter inquiry is not allowed as a list item on LINK clause
!$omp declare target link (x2%KIND)
- !ERROR: A type parameter inquiry cannot appear on the DECLARE TARGET directive
+ !ERROR: Type parameter inquiry is not allowed as a list item on LINK clause
!$omp declare target link (w2%LEN)
- !ERROR: A type parameter inquiry cannot appear on the DECLARE TARGET directive
+ !ERROR: Type parameter inquiry is not allowed as a list item on LINK clause
!$omp declare target link (y2%KIND)
end
diff --git a/flang/test/Semantics/OpenMP/from-clause-v45.f90 b/flang/test/Semantics/OpenMP/from-clause-v45.f90
index 201128fc3031c..654af4b7dd9b7 100644
--- a/flang/test/Semantics/OpenMP/from-clause-v45.f90
+++ b/flang/test/Semantics/OpenMP/from-clause-v45.f90
@@ -28,6 +28,6 @@ subroutine f03(x)
end
subroutine f04
-!ERROR: 'f04' must be a variable
+!ERROR: 'f04' must be a variable list item
!$omp target update from(f04)
end
diff --git a/flang/test/Semantics/OpenMP/from-clause-v51.f90 b/flang/test/Semantics/OpenMP/from-clause-v51.f90
index 70c00823d073e..8771f519fec03 100644
--- a/flang/test/Semantics/OpenMP/from-clause-v51.f90
+++ b/flang/test/Semantics/OpenMP/from-clause-v51.f90
@@ -13,6 +13,6 @@ subroutine f03(x)
end
subroutine f04
-!ERROR: 'f04' must be a variable
+!ERROR: 'f04' must be a locator list item
!$omp target update from(f04)
end
diff --git a/flang/test/Semantics/OpenMP/in-reduction.f90 b/flang/test/Semantics/OpenMP/in-reduction.f90
index c3fe7fee73c24..0472774704334 100644
--- a/flang/test/Semantics/OpenMP/in-reduction.f90
+++ b/flang/test/Semantics/OpenMP/in-reduction.f90
@@ -66,7 +66,7 @@ subroutine f07
subroutine f08
integer :: x
-!ERROR: Type parameter inquiry is not permitted in IN_REDUCTION clause
+!ERROR: Type parameter inquiry is not allowed as a list item on IN_REDUCTION clause
!$omp target in_reduction(+: x%kind)
!$omp end target
end
diff --git a/flang/test/Semantics/OpenMP/lastprivate01.f90 b/flang/test/Semantics/OpenMP/lastprivate01.f90
index 4fae4829d8862..4248a34e702c7 100644
--- a/flang/test/Semantics/OpenMP/lastprivate01.f90
+++ b/flang/test/Semantics/OpenMP/lastprivate01.f90
@@ -15,8 +15,7 @@ program omp_lastprivate
a = 10
b = 20
- !ERROR: Variable 'k' on the LASTPRIVATE clause is not definable
- !BECAUSE: 'k' is not a variable
+ !ERROR: 'k' must be a variable list item
!$omp parallel do lastprivate(k)
do i = 1, 10
c(i) = a(i) + b(i) + k
diff --git a/flang/test/Semantics/OpenMP/name-conflict.f90 b/flang/test/Semantics/OpenMP/name-conflict.f90
index 5babc3c6d3886..267e9774e3e4b 100644
--- a/flang/test/Semantics/OpenMP/name-conflict.f90
+++ b/flang/test/Semantics/OpenMP/name-conflict.f90
@@ -5,7 +5,7 @@ module m
subroutine foo1()
integer :: baz1
-!ERROR: 'baz1' must be a variable
+!ERROR: 'baz1' must be a variable list item
!$omp parallel do shared(baz1)
baz1: do i = 1, 100
enddo baz1
@@ -14,7 +14,7 @@ subroutine foo1()
subroutine foo2()
!implicit baz2
-!ERROR: 'baz2' must be a variable
+!ERROR: 'baz2' must be a variable list item
!$omp parallel do shared(baz2)
baz2: do i = 1, 100
enddo baz2
diff --git a/flang/test/Semantics/OpenMP/named-constants.f90 b/flang/test/Semantics/OpenMP/named-constants.f90
index ac0850066cebe..759560e0a495c 100644
--- a/flang/test/Semantics/OpenMP/named-constants.f90
+++ b/flang/test/Semantics/OpenMP/named-constants.f90
@@ -33,10 +33,10 @@ subroutine prvt()
real, parameter :: m = 7.0
logical, parameter :: l = .false.
integer, dimension(3), parameter :: a = [1, 2, 3]
- !ERROR: 'n' must be a variable
- !ERROR: 'm' must be a variable
- !ERROR: 'l' must be a variable
- !ERROR: 'a' must be a variable
+ !ERROR: 'n' must be a variable list item
+ !ERROR: 'm' must be a variable list item
+ !ERROR: 'l' must be a variable list item
+ !ERROR: 'a' must be a variable list item
!$omp parallel private(n, m, l, a)
print *, n, m, l, a
!$omp end parallel
diff --git a/flang/test/Semantics/OpenMP/reduction04.f90 b/flang/test/Semantics/OpenMP/reduction04.f90
index e86b67b6efa96..f1c8a0de6cb19 100644
--- a/flang/test/Semantics/OpenMP/reduction04.f90
+++ b/flang/test/Semantics/OpenMP/reduction04.f90
@@ -6,8 +6,7 @@ program omp_Reduction
integer, parameter :: k = 10
common /c/ a, b
- !ERROR: Variable 'k' on the REDUCTION clause is not definable
- !BECAUSE: 'k' is not a variable
+ !ERROR: 'k' must be a variable list item
!$omp parallel do reduction(+:k)
do i = 1, 10
l = k + 1
diff --git a/flang/test/Semantics/OpenMP/reduction16.f90 b/flang/test/Semantics/OpenMP/reduction16.f90
index 6bb218e306128..0c92a5b9d2d6d 100644
--- a/flang/test/Semantics/OpenMP/reduction16.f90
+++ b/flang/test/Semantics/OpenMP/reduction16.f90
@@ -5,7 +5,7 @@
subroutine f00
integer :: x
-!ERROR: Type parameter inquiry is not permitted in REDUCTION clause
+!ERROR: Type parameter inquiry is not allowed as a list item on REDUCTION clause
!$omp do reduction (+ : x%kind)
do i = 1, 10
end do
diff --git a/flang/test/Semantics/OpenMP/task-reduction.f90 b/flang/test/Semantics/OpenMP/task-reduction.f90
index baa363bdd00ad..7e43332d53fe1 100644
--- a/flang/test/Semantics/OpenMP/task-reduction.f90
+++ b/flang/test/Semantics/OpenMP/task-reduction.f90
@@ -66,7 +66,7 @@ subroutine f07
subroutine f08
integer :: x
-!ERROR: Type parameter inquiry is not permitted in TASK_REDUCTION clause
+!ERROR: Type parameter inquiry is not allowed as a list item on TASK_REDUCTION clause
!$omp taskgroup task_reduction(+: x%kind)
!$omp end taskgroup
end
diff --git a/flang/test/Semantics/OpenMP/to-clause-v45.f90 b/flang/test/Semantics/OpenMP/to-clause-v45.f90
index 9797c06cdeddf..7e56817e1ff7c 100644
--- a/flang/test/Semantics/OpenMP/to-clause-v45.f90
+++ b/flang/test/Semantics/OpenMP/to-clause-v45.f90
@@ -28,6 +28,6 @@ subroutine f03(x)
end
subroutine f04
-!ERROR: 'f04' must be a variable
+!ERROR: 'f04' must be a variable list item
!$omp target update to(f04)
end
diff --git a/flang/test/Semantics/OpenMP/to-clause-v51.f90 b/flang/test/Semantics/OpenMP/to-clause-v51.f90
index 8abbca3bb07cd..0db292a22238b 100644
--- a/flang/test/Semantics/OpenMP/to-clause-v51.f90
+++ b/flang/test/Semantics/OpenMP/to-clause-v51.f90
@@ -13,6 +13,6 @@ subroutine f03(x)
end
subroutine f04
-!ERROR: 'f04' must be a variable
+!ERROR: 'f04' must be a locator list item
!$omp target update to(f04)
end
More information about the flang-commits
mailing list