Skip to content

Commit ac8f13c

Browse files
committed
[flang][OpenMP] Fix scope checks for ALLOCATE directive
Make sure that the ALLOCATE directive adds its source span to the current scope, and that the scope checks compare scoping units, not the specific scopes.
1 parent 5cb1641 commit ac8f13c

File tree

6 files changed

+39
-37
lines changed

6 files changed

+39
-37
lines changed

flang/lib/Semantics/resolve-directives.cpp

Lines changed: 31 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,24 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor<llvm::omp::Directive> {
362362
explicit OmpAttributeVisitor(SemanticsContext &context)
363363
: DirectiveAttributeVisitor(context) {}
364364

365+
static const Scope &scopingUnit(const Scope &scope) {
366+
const Scope *iter{&scope};
367+
for (; !iter->IsTopLevel(); iter = &iter->parent()) {
368+
switch (iter->kind()) {
369+
case Scope::Kind::BlockConstruct:
370+
case Scope::Kind::BlockData:
371+
case Scope::Kind::DerivedType:
372+
case Scope::Kind::MainProgram:
373+
case Scope::Kind::Module:
374+
case Scope::Kind::Subprogram:
375+
return *iter;
376+
default:
377+
break;
378+
}
379+
}
380+
return *iter;
381+
}
382+
365383
template <typename A> void Walk(const A &x) { parser::Walk(x, *this); }
366384
template <typename A> bool Pre(const A &) { return true; }
367385
template <typename A> void Post(const A &) {}
@@ -952,7 +970,6 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor<llvm::omp::Directive> {
952970
void ResolveOmpNameList(const std::list<parser::Name> &, Symbol::Flag);
953971
void ResolveOmpName(const parser::Name &, Symbol::Flag);
954972
Symbol *ResolveName(const parser::Name *);
955-
Symbol *ResolveOmpObjectScope(const parser::Name *);
956973
Symbol *DeclareOrMarkOtherAccessEntity(const parser::Name &, Symbol::Flag);
957974
Symbol *DeclareOrMarkOtherAccessEntity(Symbol &, Symbol::Flag);
958975
void CheckMultipleAppearances(
@@ -2925,31 +2942,6 @@ Symbol *OmpAttributeVisitor::ResolveOmpCommonBlockName(
29252942
return nullptr;
29262943
}
29272944

2928-
// Use this function over ResolveOmpName when an omp object's scope needs
2929-
// resolving, it's symbol flag isn't important and a simple check for resolution
2930-
// failure is desired. Using ResolveOmpName means needing to work with the
2931-
// context to check for failure, whereas here a pointer comparison is all that's
2932-
// needed.
2933-
Symbol *OmpAttributeVisitor::ResolveOmpObjectScope(const parser::Name *name) {
2934-
2935-
// TODO: Investigate whether the following block can be replaced by, or
2936-
// included in, the ResolveOmpName function
2937-
if (auto *prev{name ? GetContext().scope.parent().FindSymbol(name->source)
2938-
: nullptr}) {
2939-
name->symbol = prev;
2940-
return nullptr;
2941-
}
2942-
2943-
// TODO: Investigate whether the following block can be replaced by, or
2944-
// included in, the ResolveOmpName function
2945-
if (auto *ompSymbol{
2946-
name ? GetContext().scope.FindSymbol(name->source) : nullptr}) {
2947-
name->symbol = ompSymbol;
2948-
return ompSymbol;
2949-
}
2950-
return nullptr;
2951-
}
2952-
29532945
void OmpAttributeVisitor::ResolveOmpObjectList(
29542946
const parser::OmpObjectList &ompObjectList, Symbol::Flag ompFlag) {
29552947
for (const auto &ompObject : ompObjectList.v) {
@@ -3028,13 +3020,19 @@ void OmpAttributeVisitor::ResolveOmpDesignator(
30283020
context_.Say(designator.source,
30293021
"List items specified in the ALLOCATE directive must not have the ALLOCATABLE attribute unless the directive is associated with an ALLOCATE statement"_err_en_US);
30303022
}
3031-
if ((ompFlag == Symbol::Flag::OmpDeclarativeAllocateDirective ||
3032-
ompFlag == Symbol::Flag::OmpExecutableAllocateDirective) &&
3033-
ResolveOmpObjectScope(name) == nullptr) {
3034-
context_.Say(designator.source, // 2.15.3
3035-
"List items must be declared in the same scoping unit in which the %s directive appears"_err_en_US,
3036-
parser::ToUpperCaseLetters(
3037-
llvm::omp::getOpenMPDirectiveName(directive, version)));
3023+
bool checkScope{ompFlag == Symbol::Flag::OmpDeclarativeAllocateDirective};
3024+
// In 5.1 the scope check only applies to declarative allocate.
3025+
if (version == 50 && !checkScope) {
3026+
checkScope = ompFlag == Symbol::Flag::OmpExecutableAllocateDirective;
3027+
}
3028+
if (checkScope) {
3029+
if (scopingUnit(GetContext().scope) !=
3030+
scopingUnit(symbol->GetUltimate().owner())) {
3031+
context_.Say(designator.source, // 2.15.3
3032+
"List items must be declared in the same scoping unit in which the %s directive appears"_err_en_US,
3033+
parser::ToUpperCaseLetters(
3034+
llvm::omp::getOpenMPDirectiveName(directive, version)));
3035+
}
30383036
}
30393037
if (ompFlag == Symbol::Flag::OmpReduction) {
30403038
// Using variables inside of a namelist in OpenMP reductions

flang/lib/Semantics/resolve-names.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1627,12 +1627,14 @@ class OmpVisitor : public virtual DeclarationVisitor {
16271627
void Post(const parser::OpenMPDeclareTargetConstruct &) {
16281628
SkipImplicitTyping(false);
16291629
}
1630-
bool Pre(const parser::OpenMPDeclarativeAllocate &) {
1630+
bool Pre(const parser::OpenMPDeclarativeAllocate &x) {
1631+
AddOmpSourceRange(x.source);
16311632
SkipImplicitTyping(true);
16321633
return true;
16331634
}
16341635
void Post(const parser::OpenMPDeclarativeAllocate &) {
16351636
SkipImplicitTyping(false);
1637+
messageHandler().set_currStmtSource(std::nullopt);
16361638
}
16371639
bool Pre(const parser::OpenMPDeclarativeConstruct &x) {
16381640
AddOmpSourceRange(x.source);

flang/test/Semantics/OpenMP/allocate01.f90

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ subroutine sema()
2020
print *, a
2121

2222
!WARNING: OpenMP directive ALLOCATE has been deprecated, please use ALLOCATORS instead. [-Wopen-mp-usage]
23-
!ERROR: List items must be declared in the same scoping unit in which the ALLOCATE directive appears
2423
!$omp allocate(x) allocator(omp_default_mem_alloc)
2524
allocate ( x(a), darray(a, b) )
2625
end subroutine sema

flang/test/Semantics/OpenMP/allocate08.f90

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,12 @@ subroutine allocate()
2727

2828
!$omp allocate(x) allocator(omp_default_mem_alloc)
2929
!$omp allocate(y) allocator(omp_default_mem_alloc)
30+
!ERROR: List items must be declared in the same scoping unit in which the ALLOCATE directive appears
3031
!$omp allocate(z) allocator(omp_default_mem_alloc)
3132

3233
!$omp allocate(x)
3334
!$omp allocate(y)
35+
!ERROR: List items must be declared in the same scoping unit in which the ALLOCATE directive appears
3436
!$omp allocate(z)
3537

3638
!$omp allocate(w) allocator(custom_allocator)
@@ -40,5 +42,6 @@ subroutine allocate()
4042
!ERROR: If list items within the ALLOCATE directive have the SAVE attribute, are a common block name, or are declared in the scope of a module, then only predefined memory allocator parameters can be used in the allocator clause
4143
!$omp allocate(y) allocator(custom_allocator)
4244
!ERROR: If list items within the ALLOCATE directive have the SAVE attribute, are a common block name, or are declared in the scope of a module, then only predefined memory allocator parameters can be used in the allocator clause
45+
!ERROR: List items must be declared in the same scoping unit in which the ALLOCATE directive appears
4346
!$omp allocate(z) allocator(custom_allocator)
4447
end subroutine allocate

flang/test/Semantics/OpenMP/allocators04.f90

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,12 @@ subroutine allocate()
2222
trait(1)%value = default_mem_fb
2323
custom_allocator = omp_init_allocator(omp_default_mem_space, 1, trait)
2424

25+
!ERROR: List items must be declared in the same scoping unit in which the ALLOCATORS directive appears
2526
!$omp allocators allocate(omp_default_mem_alloc: a)
2627
allocate(a)
2728

2829
!ERROR: If list items within the ALLOCATORS directive have the SAVE attribute, are a common block name, or are declared in the scope of a module, then only predefined memory allocator parameters can be used in the allocator clause
30+
!ERROR: List items must be declared in the same scoping unit in which the ALLOCATORS directive appears
2931
!$omp allocators allocate(custom_allocator: b)
3032
allocate(b)
3133
end subroutine

flang/test/Semantics/OpenMP/allocators05.f90

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,9 @@ subroutine allocate()
1515
integer, parameter :: LEN = 2
1616

1717
!$omp target private(a, b)
18-
!ERROR: List items must be declared in the same scoping unit in which the ALLOCATORS directive appears
1918
!$omp allocators allocate(omp_default_mem_alloc: a)
2019
allocate(a(LEN))
2120
!ERROR: ALLOCATORS directives that appear in a TARGET region must specify an allocator
22-
!ERROR: List items must be declared in the same scoping unit in which the ALLOCATORS directive appears
2321
!$omp allocators allocate(b)
2422
allocate(b(LEN))
2523
!$omp end target

0 commit comments

Comments
 (0)