aboutsummaryrefslogtreecommitdiff
path: root/flang/lib/Semantics/check-omp-structure.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'flang/lib/Semantics/check-omp-structure.cpp')
-rw-r--r--flang/lib/Semantics/check-omp-structure.cpp57
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");
+ }
}
}
}