Skip to content

Commit 888ceac

Browse files
authored
[flang][OpenMP] Analyze objects in OmpObjectList on clauses (#155424) (#155667)
This is intended to diagnose errors such as incorrect uses of assumed-size arrays, for example. Fixes #151990 Reinstate 6308531 (PR 155424) with a change that treats whole assumed- size-arrays as variables (as defined by the Fortran standard). This treats them, by default, as valid variable list items.
1 parent 4b562f9 commit 888ceac

File tree

6 files changed

+55
-4
lines changed

6 files changed

+55
-4
lines changed

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

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,41 @@ bool OmpStructureChecker::CheckAllowedClause(llvmOmpClause clause) {
268268
return CheckAllowed(clause);
269269
}
270270

271+
void OmpStructureChecker::AnalyzeObject(const parser::OmpObject &object) {
272+
if (std::holds_alternative<parser::Name>(object.u)) {
273+
// Do not analyze common block names. The analyzer will flag an error
274+
// on those.
275+
return;
276+
}
277+
if (auto *symbol{GetObjectSymbol(object)}) {
278+
// Eliminate certain kinds of symbols before running the analyzer to
279+
// avoid confusing error messages. The analyzer assumes that the context
280+
// of the object use is an expression, and some diagnostics are tailored
281+
// to that.
282+
if (symbol->has<DerivedTypeDetails>() || symbol->has<MiscDetails>()) {
283+
// Type names, construct names, etc.
284+
return;
285+
}
286+
if (auto *typeSpec{symbol->GetType()}) {
287+
if (typeSpec->category() == DeclTypeSpec::Category::Character) {
288+
// Don't pass character objects to the analyzer, it can emit somewhat
289+
// cryptic errors (e.g. "'obj' is not an array"). Substrings are
290+
// checked elsewhere in OmpStructureChecker.
291+
return;
292+
}
293+
}
294+
}
295+
evaluate::ExpressionAnalyzer ea{context_};
296+
auto restore{ea.AllowWholeAssumedSizeArray(true)};
297+
common::visit([&](auto &&s) { ea.Analyze(s); }, object.u);
298+
}
299+
300+
void OmpStructureChecker::AnalyzeObjects(const parser::OmpObjectList &objects) {
301+
for (const parser::OmpObject &object : objects.v) {
302+
AnalyzeObject(object);
303+
}
304+
}
305+
271306
bool OmpStructureChecker::IsCloselyNestedRegion(const OmpDirectiveSet &set) {
272307
// Definition of close nesting:
273308
//
@@ -2697,8 +2732,9 @@ void OmpStructureChecker::Leave(const parser::OmpClauseList &) {
26972732
void OmpStructureChecker::Enter(const parser::OmpClause &x) {
26982733
SetContextClause(x);
26992734

2735+
llvm::omp::Clause id{x.Id()};
27002736
// The visitors for these clauses do their own checks.
2701-
switch (x.Id()) {
2737+
switch (id) {
27022738
case llvm::omp::Clause::OMPC_copyprivate:
27032739
case llvm::omp::Clause::OMPC_enter:
27042740
case llvm::omp::Clause::OMPC_lastprivate:
@@ -2712,7 +2748,7 @@ void OmpStructureChecker::Enter(const parser::OmpClause &x) {
27122748
// Named constants are OK to be used within 'shared' and 'firstprivate'
27132749
// clauses. The check for this happens a few lines below.
27142750
bool SharedOrFirstprivate = false;
2715-
switch (x.Id()) {
2751+
switch (id) {
27162752
case llvm::omp::Clause::OMPC_shared:
27172753
case llvm::omp::Clause::OMPC_firstprivate:
27182754
SharedOrFirstprivate = true;
@@ -2722,6 +2758,7 @@ void OmpStructureChecker::Enter(const parser::OmpClause &x) {
27222758
}
27232759

27242760
if (const parser::OmpObjectList *objList{GetOmpObjectList(x)}) {
2761+
AnalyzeObjects(*objList);
27252762
SymbolSourceMap symbols;
27262763
GetSymbolsInObjectList(*objList, symbols);
27272764
for (const auto &[symbol, source] : symbols) {

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,8 @@ class OmpStructureChecker
167167
void CheckVariableListItem(const SymbolSourceMap &symbols);
168168
void CheckDirectiveSpelling(
169169
parser::CharBlock spelling, llvm::omp::Directive id);
170+
void AnalyzeObject(const parser::OmpObject &object);
171+
void AnalyzeObjects(const parser::OmpObjectList &objects);
170172
void CheckMultipleOccurrence(semantics::UnorderedSymbolSet &listVars,
171173
const std::list<parser::Name> &nameList, const parser::CharBlock &item,
172174
const std::string &clauseName);

flang/test/Lower/OpenMP/Todo/omp-do-simd-linear.f90

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
! RUN: %not_todo_cmd bbc -emit-fir -fopenmp -o - %s 2>&1 | FileCheck %s
44
! RUN: %not_todo_cmd %flang_fc1 -emit-fir -fopenmp -o - %s 2>&1 | FileCheck %s
55
subroutine testDoSimdLinear(int_array)
6-
integer :: int_array(*)
6+
integer :: int_array(:)
77
!CHECK: not yet implemented: Unhandled clause LINEAR in SIMD construct
88
!$omp do simd linear(int_array)
99
do index_ = 1, 10

flang/test/Semantics/OpenMP/declare-mapper02.f90

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,6 @@
66
end type t1
77

88
!ERROR: ABSTRACT derived type may not be used here
9+
!ERROR: Reference to object with abstract derived type 't1' must be polymorphic
910
!$omp declare mapper(mm : t1::x) map(x, x%y)
1011
end

flang/test/Semantics/OpenMP/depend01.f90

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ program omp_depend
2020
!ERROR: 'a' in DEPEND clause must have a positive stride
2121
!ERROR: 'b' in DEPEND clause must have a positive stride
2222
!ERROR: 'b' in DEPEND clause is a zero size array section
23-
!$omp task shared(x) depend(in: a(10:5:-1)) depend(in: b(5:10:-1))
23+
!$omp task shared(x) depend(in: a(10:5:-1)) depend(in: b(5:10:-1, 2))
2424
print *, a(5:10), b
2525
!$omp end task
2626

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 -fopenmp -fopenmp-version=45
2+
3+
subroutine foo(x)
4+
integer :: x(3, *)
5+
!$omp task depend(in:x(:,5))
6+
!$omp end task
7+
!ERROR: Assumed-size array 'x' must have explicit final subscript upper bound value
8+
!$omp task depend(in:x(5,:))
9+
!$omp end task
10+
end
11+

0 commit comments

Comments
 (0)