Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 31 additions & 33 deletions flang/lib/Semantics/resolve-directives.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,24 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor<llvm::omp::Directive> {
explicit OmpAttributeVisitor(SemanticsContext &context)
: DirectiveAttributeVisitor(context) {}

static const Scope &scopingUnit(const Scope &scope) {
const Scope *iter{&scope};
for (; !iter->IsTopLevel(); iter = &iter->parent()) {
switch (iter->kind()) {
case Scope::Kind::BlockConstruct:
case Scope::Kind::BlockData:
case Scope::Kind::DerivedType:
case Scope::Kind::MainProgram:
case Scope::Kind::Module:
case Scope::Kind::Subprogram:
return *iter;
default:
break;
}
}
return *iter;
}

template <typename A> void Walk(const A &x) { parser::Walk(x, *this); }
template <typename A> bool Pre(const A &) { return true; }
template <typename A> void Post(const A &) {}
Expand Down Expand Up @@ -952,7 +970,6 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor<llvm::omp::Directive> {
void ResolveOmpNameList(const std::list<parser::Name> &, Symbol::Flag);
void ResolveOmpName(const parser::Name &, Symbol::Flag);
Symbol *ResolveName(const parser::Name *);
Symbol *ResolveOmpObjectScope(const parser::Name *);
Symbol *DeclareOrMarkOtherAccessEntity(const parser::Name &, Symbol::Flag);
Symbol *DeclareOrMarkOtherAccessEntity(Symbol &, Symbol::Flag);
void CheckMultipleAppearances(
Expand Down Expand Up @@ -2925,31 +2942,6 @@ Symbol *OmpAttributeVisitor::ResolveOmpCommonBlockName(
return nullptr;
}

// Use this function over ResolveOmpName when an omp object's scope needs
// resolving, it's symbol flag isn't important and a simple check for resolution
// failure is desired. Using ResolveOmpName means needing to work with the
// context to check for failure, whereas here a pointer comparison is all that's
// needed.
Symbol *OmpAttributeVisitor::ResolveOmpObjectScope(const parser::Name *name) {

// TODO: Investigate whether the following block can be replaced by, or
// included in, the ResolveOmpName function
if (auto *prev{name ? GetContext().scope.parent().FindSymbol(name->source)
: nullptr}) {
name->symbol = prev;
return nullptr;
}

// TODO: Investigate whether the following block can be replaced by, or
// included in, the ResolveOmpName function
if (auto *ompSymbol{
name ? GetContext().scope.FindSymbol(name->source) : nullptr}) {
name->symbol = ompSymbol;
return ompSymbol;
}
return nullptr;
}

void OmpAttributeVisitor::ResolveOmpObjectList(
const parser::OmpObjectList &ompObjectList, Symbol::Flag ompFlag) {
for (const auto &ompObject : ompObjectList.v) {
Expand Down Expand Up @@ -3028,13 +3020,19 @@ void OmpAttributeVisitor::ResolveOmpDesignator(
context_.Say(designator.source,
"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);
}
if ((ompFlag == Symbol::Flag::OmpDeclarativeAllocateDirective ||
ompFlag == Symbol::Flag::OmpExecutableAllocateDirective) &&
ResolveOmpObjectScope(name) == nullptr) {
context_.Say(designator.source, // 2.15.3
"List items must be declared in the same scoping unit in which the %s directive appears"_err_en_US,
parser::ToUpperCaseLetters(
llvm::omp::getOpenMPDirectiveName(directive, version)));
bool checkScope{ompFlag == Symbol::Flag::OmpDeclarativeAllocateDirective};
// In 5.1 the scope check only applies to declarative allocate.
if (version == 50 && !checkScope) {
checkScope = ompFlag == Symbol::Flag::OmpExecutableAllocateDirective;
}
if (checkScope) {
if (scopingUnit(GetContext().scope) !=
scopingUnit(symbol->GetUltimate().owner())) {
context_.Say(designator.source, // 2.15.3
"List items must be declared in the same scoping unit in which the %s directive appears"_err_en_US,
parser::ToUpperCaseLetters(
llvm::omp::getOpenMPDirectiveName(directive, version)));
}
}
if (ompFlag == Symbol::Flag::OmpReduction) {
// Using variables inside of a namelist in OpenMP reductions
Expand Down
4 changes: 3 additions & 1 deletion flang/lib/Semantics/resolve-names.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1627,12 +1627,14 @@ class OmpVisitor : public virtual DeclarationVisitor {
void Post(const parser::OpenMPDeclareTargetConstruct &) {
SkipImplicitTyping(false);
}
bool Pre(const parser::OpenMPDeclarativeAllocate &) {
bool Pre(const parser::OpenMPDeclarativeAllocate &x) {
AddOmpSourceRange(x.source);
SkipImplicitTyping(true);
return true;
}
void Post(const parser::OpenMPDeclarativeAllocate &) {
SkipImplicitTyping(false);
messageHandler().set_currStmtSource(std::nullopt);
}
bool Pre(const parser::OpenMPDeclarativeConstruct &x) {
AddOmpSourceRange(x.source);
Expand Down
1 change: 0 additions & 1 deletion flang/test/Semantics/OpenMP/allocate01.f90
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ subroutine sema()
print *, a

!WARNING: OpenMP directive ALLOCATE has been deprecated, please use ALLOCATORS instead. [-Wopen-mp-usage]
!ERROR: List items must be declared in the same scoping unit in which the ALLOCATE directive appears
!$omp allocate(x) allocator(omp_default_mem_alloc)
allocate ( x(a), darray(a, b) )
end subroutine sema
Expand Down
3 changes: 3 additions & 0 deletions flang/test/Semantics/OpenMP/allocate08.f90
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,12 @@ subroutine allocate()

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

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

!$omp allocate(w) allocator(custom_allocator)
Expand All @@ -40,5 +42,6 @@ subroutine allocate()
!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
!$omp allocate(y) allocator(custom_allocator)
!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
!ERROR: List items must be declared in the same scoping unit in which the ALLOCATE directive appears
!$omp allocate(z) allocator(custom_allocator)
end subroutine allocate
2 changes: 2 additions & 0 deletions flang/test/Semantics/OpenMP/allocators04.f90
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,12 @@ subroutine allocate()
trait(1)%value = default_mem_fb
custom_allocator = omp_init_allocator(omp_default_mem_space, 1, trait)

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

!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
!ERROR: List items must be declared in the same scoping unit in which the ALLOCATORS directive appears
!$omp allocators allocate(custom_allocator: b)
allocate(b)
end subroutine
2 changes: 0 additions & 2 deletions flang/test/Semantics/OpenMP/allocators05.f90
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,9 @@ subroutine allocate()
integer, parameter :: LEN = 2

!$omp target private(a, b)
!ERROR: List items must be declared in the same scoping unit in which the ALLOCATORS directive appears
!$omp allocators allocate(omp_default_mem_alloc: a)
allocate(a(LEN))
!ERROR: ALLOCATORS directives that appear in a TARGET region must specify an allocator
!ERROR: List items must be declared in the same scoping unit in which the ALLOCATORS directive appears
!$omp allocators allocate(b)
allocate(b(LEN))
!$omp end target
Expand Down