diff options
Diffstat (limited to 'flang/lib/Semantics/check-omp-structure.cpp')
-rw-r--r-- | flang/lib/Semantics/check-omp-structure.cpp | 57 |
1 files changed, 33 insertions, 24 deletions
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp index 8264e1d..d214d22 100644 --- a/flang/lib/Semantics/check-omp-structure.cpp +++ b/flang/lib/Semantics/check-omp-structure.cpp @@ -16,7 +16,6 @@ #include "flang/Common/idioms.h" #include "flang/Common/indirection.h" #include "flang/Common/visit.h" -#include "flang/Evaluate/shape.h" #include "flang/Evaluate/tools.h" #include "flang/Evaluate/type.h" #include "flang/Parser/char-block.h" @@ -782,12 +781,15 @@ void OmpStructureChecker::CheckTargetNest(const parser::OpenMPConstruct &c) { void OmpStructureChecker::Enter(const parser::OpenMPBlockConstruct &x) { const auto &beginBlockDir{std::get<parser::OmpBeginBlockDirective>(x.t)}; - const auto &endBlockDir{std::get<parser::OmpEndBlockDirective>(x.t)}; + const auto &endBlockDir{ + std::get<std::optional<parser::OmpEndBlockDirective>>(x.t)}; const auto &beginDir{std::get<parser::OmpBlockDirective>(beginBlockDir.t)}; - const auto &endDir{std::get<parser::OmpBlockDirective>(endBlockDir.t)}; const parser::Block &block{std::get<parser::Block>(x.t)}; - CheckMatching<parser::OmpBlockDirective>(beginDir, endDir); + if (endBlockDir) { + const auto &endDir{std::get<parser::OmpBlockDirective>(endBlockDir->t)}; + CheckMatching<parser::OmpBlockDirective>(beginDir, endDir); + } PushContextAndClauseSets(beginDir.source, beginDir.v); if (llvm::omp::allTargetSet.test(GetContext().directive)) { @@ -837,14 +839,14 @@ void OmpStructureChecker::Enter(const parser::OpenMPBlockConstruct &x) { bool foundNowait{false}; parser::CharBlock NowaitSource; - auto catchCopyPrivateNowaitClauses = [&](const auto &dir, bool endDir) { + auto catchCopyPrivateNowaitClauses = [&](const auto &dir, bool isEnd) { for (auto &clause : std::get<parser::OmpClauseList>(dir.t).v) { if (clause.Id() == llvm::omp::Clause::OMPC_copyprivate) { for (const auto &ompObject : GetOmpObjectList(clause)->v) { const auto *name{parser::Unwrap<parser::Name>(ompObject)}; if (Symbol * symbol{name->symbol}) { if (singleCopyprivateSyms.count(symbol)) { - if (endDir) { + if (isEnd) { context_.Warn(common::UsageWarning::OpenMPUsage, name->source, "The COPYPRIVATE clause with '%s' is already used on the SINGLE directive"_warn_en_US, name->ToString()); @@ -858,7 +860,7 @@ void OmpStructureChecker::Enter(const parser::OpenMPBlockConstruct &x) { "'%s' appears in more than one COPYPRIVATE clause on the END SINGLE directive"_err_en_US, name->ToString()); } else { - if (endDir) { + if (isEnd) { endSingleCopyprivateSyms.insert(symbol); } else { singleCopyprivateSyms.insert(symbol); @@ -871,7 +873,7 @@ void OmpStructureChecker::Enter(const parser::OpenMPBlockConstruct &x) { context_.Say(clause.source, "At most one NOWAIT clause can appear on the SINGLE directive"_err_en_US); } else { - foundNowait = !endDir; + foundNowait = !isEnd; } if (!NowaitSource.ToString().size()) { NowaitSource = clause.source; @@ -880,7 +882,9 @@ void OmpStructureChecker::Enter(const parser::OpenMPBlockConstruct &x) { } }; catchCopyPrivateNowaitClauses(beginBlockDir, false); - catchCopyPrivateNowaitClauses(endBlockDir, true); + if (endBlockDir) { + catchCopyPrivateNowaitClauses(*endBlockDir, true); + } unsigned version{context_.langOptions().OpenMPVersion}; if (version <= 52 && NowaitSource.ToString().size() && (singleCopyprivateSyms.size() || endSingleCopyprivateSyms.size())) { @@ -4151,21 +4155,26 @@ void OmpStructureChecker::CheckArraySection( // Detect this by looking for array accesses on character variables which are // not arrays. bool isSubstring{false}; - evaluate::ExpressionAnalyzer ea{context_}; - if (MaybeExpr expr = ea.Analyze(arrayElement.base)) { - std::optional<evaluate::Shape> shape = evaluate::GetShape(expr); - // Not an array: rank 0 - if (shape && shape->size() == 0) { - if (std::optional<evaluate::DynamicType> type = expr->GetType()) { - if (type->category() == evaluate::TypeCategory::Character) { - // Substrings are explicitly denied by the standard [6.0:163:9-11]. - // This is supported as an extension. This restriction was added in - // OpenMP 5.2. - isSubstring = true; - context_.Say(GetContext().clauseSource, - "The use of substrings in OpenMP argument lists has been disallowed since OpenMP 5.2."_port_en_US); - } else { - llvm_unreachable("Array indexing on a variable that isn't an array"); + // Cannot analyze a base of an assumed-size array on its own. If we know + // this is an array (assumed-size or not) we can ignore it, since we're + // looking for strings. + if (!IsAssumedSizeArray(*name.symbol)) { + evaluate::ExpressionAnalyzer ea{context_}; + if (MaybeExpr expr = ea.Analyze(arrayElement.base)) { + if (expr->Rank() == 0) { + // Not an array: rank 0 + if (std::optional<evaluate::DynamicType> type = expr->GetType()) { + if (type->category() == evaluate::TypeCategory::Character) { + // Substrings are explicitly denied by the standard [6.0:163:9-11]. + // This is supported as an extension. This restriction was added in + // OpenMP 5.2. + isSubstring = true; + context_.Say(GetContext().clauseSource, + "The use of substrings in OpenMP argument lists has been disallowed since OpenMP 5.2."_port_en_US); + } else { + llvm_unreachable( + "Array indexing on a variable that isn't an array"); + } } } } |