Skip to content

Commit 57c354f

Browse files
kparzyszmahesh-attarde
authored andcommitted
[flang][OpenMP] Fix scope checks for ALLOCATE directive (llvm#160948)
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 a05c4c9 commit 57c354f

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(
@@ -2920,31 +2937,6 @@ Symbol *OmpAttributeVisitor::ResolveOmpCommonBlockName(
29202937
return nullptr;
29212938
}
29222939

2923-
// Use this function over ResolveOmpName when an omp object's scope needs
2924-
// resolving, it's symbol flag isn't important and a simple check for resolution
2925-
// failure is desired. Using ResolveOmpName means needing to work with the
2926-
// context to check for failure, whereas here a pointer comparison is all that's
2927-
// needed.
2928-
Symbol *OmpAttributeVisitor::ResolveOmpObjectScope(const parser::Name *name) {
2929-
2930-
// TODO: Investigate whether the following block can be replaced by, or
2931-
// included in, the ResolveOmpName function
2932-
if (auto *prev{name ? GetContext().scope.parent().FindSymbol(name->source)
2933-
: nullptr}) {
2934-
name->symbol = prev;
2935-
return nullptr;
2936-
}
2937-
2938-
// TODO: Investigate whether the following block can be replaced by, or
2939-
// included in, the ResolveOmpName function
2940-
if (auto *ompSymbol{
2941-
name ? GetContext().scope.FindSymbol(name->source) : nullptr}) {
2942-
name->symbol = ompSymbol;
2943-
return ompSymbol;
2944-
}
2945-
return nullptr;
2946-
}
2947-
29482940
void OmpAttributeVisitor::ResolveOmpObjectList(
29492941
const parser::OmpObjectList &ompObjectList, Symbol::Flag ompFlag) {
29502942
for (const auto &ompObject : ompObjectList.v) {
@@ -3023,13 +3015,19 @@ void OmpAttributeVisitor::ResolveOmpDesignator(
30233015
context_.Say(designator.source,
30243016
"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);
30253017
}
3026-
if ((ompFlag == Symbol::Flag::OmpDeclarativeAllocateDirective ||
3027-
ompFlag == Symbol::Flag::OmpExecutableAllocateDirective) &&
3028-
ResolveOmpObjectScope(name) == nullptr) {
3029-
context_.Say(designator.source, // 2.15.3
3030-
"List items must be declared in the same scoping unit in which the %s directive appears"_err_en_US,
3031-
parser::ToUpperCaseLetters(
3032-
llvm::omp::getOpenMPDirectiveName(directive, version)));
3018+
bool checkScope{ompFlag == Symbol::Flag::OmpDeclarativeAllocateDirective};
3019+
// In 5.1 the scope check only applies to declarative allocate.
3020+
if (version == 50 && !checkScope) {
3021+
checkScope = ompFlag == Symbol::Flag::OmpExecutableAllocateDirective;
3022+
}
3023+
if (checkScope) {
3024+
if (scopingUnit(GetContext().scope) !=
3025+
scopingUnit(symbol->GetUltimate().owner())) {
3026+
context_.Say(designator.source, // 2.15.3
3027+
"List items must be declared in the same scoping unit in which the %s directive appears"_err_en_US,
3028+
parser::ToUpperCaseLetters(
3029+
llvm::omp::getOpenMPDirectiveName(directive, version)));
3030+
}
30333031
}
30343032
if (ompFlag == Symbol::Flag::OmpReduction) {
30353033
// 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
@@ -1618,12 +1618,14 @@ class OmpVisitor : public virtual DeclarationVisitor {
16181618
void Post(const parser::OpenMPDeclareTargetConstruct &) {
16191619
SkipImplicitTyping(false);
16201620
}
1621-
bool Pre(const parser::OpenMPDeclarativeAllocate &) {
1621+
bool Pre(const parser::OpenMPDeclarativeAllocate &x) {
1622+
AddOmpSourceRange(x.source);
16221623
SkipImplicitTyping(true);
16231624
return true;
16241625
}
16251626
void Post(const parser::OpenMPDeclarativeAllocate &) {
16261627
SkipImplicitTyping(false);
1628+
messageHandler().set_currStmtSource(std::nullopt);
16271629
}
16281630
bool Pre(const parser::OpenMPDeclarativeConstruct &x) {
16291631
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)