Skip to content

Commit

Permalink
[flang] Warn about construct names that are not distinct in the inclu…
Browse files Browse the repository at this point in the history
…sive scope

f18 implements BLOCK scoping for construct names, like most but not all Fortran
compilers, but in the 2018 standard such names are defined to be local identifiers
whose scope is the inclusive scope -- i.e., the subprogram or main program.
Detect usage that depends on this extension and emit a portability warning.

Differential Revision: https://reviews.llvm.org/D143776
  • Loading branch information
klausler committed Feb 12, 2023
1 parent 129eb5b commit 594700c
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 2 deletions.
5 changes: 5 additions & 0 deletions flang/docs/Extensions.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,11 @@ end
kind 4, because the grammar of Fortran expressions parses it as a
negation of a literal constant, not a negative literal constant.
This compiler accepts it with a portability warning.
* Construct names like `loop` in `loop: do j=1,n` are defined to
be "local identifiers" and should be distinct in the "inclusive
scope" -- i.e., not scoped by `BLOCK` constructs.
As most (but not all) compilers implement `BLOCK` scoping of construct
names, so does f18, with a portability warning.

## Extensions, deletions, and legacy features supported by default

Expand Down
30 changes: 28 additions & 2 deletions flang/lib/Semantics/resolve-names.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -553,6 +553,7 @@ class ScopeHandler : public ImplicitRulesVisitor {
// Search for name in a derived type scope and its parents.
Symbol *FindInTypeOrParents(const Scope &, const parser::Name &);
Symbol *FindInTypeOrParents(const parser::Name &);
Symbol *FindInScopeOrBlockConstructs(const Scope &, SourceName);
Symbol *FindSeparateModuleProcedureInterface(const parser::Name &);
void EraseSymbol(const parser::Name &);
void EraseSymbol(const Symbol &symbol) { currScope().erase(symbol.name()); }
Expand Down Expand Up @@ -2369,6 +2370,20 @@ Symbol *ScopeHandler::FindInTypeOrParents(
Symbol *ScopeHandler::FindInTypeOrParents(const parser::Name &name) {
return FindInTypeOrParents(currScope(), name);
}
Symbol *ScopeHandler::FindInScopeOrBlockConstructs(
const Scope &scope, SourceName name) {
if (Symbol * symbol{FindInScope(scope, name)}) {
return symbol;
}
for (const Scope &child : scope.children()) {
if (child.kind() == Scope::Kind::BlockConstruct) {
if (Symbol * symbol{FindInScopeOrBlockConstructs(child, name)}) {
return symbol;
}
}
}
return nullptr;
}

void ScopeHandler::EraseSymbol(const parser::Name &name) {
currScope().erase(name.source);
Expand Down Expand Up @@ -6556,8 +6571,19 @@ void ConstructVisitor::Post(const parser::SelectRankConstruct &) {
}

bool ConstructVisitor::CheckDef(const std::optional<parser::Name> &x) {
if (x) {
MakeSymbol(*x, MiscDetails{MiscDetails::Kind::ConstructName});
if (x && !x->symbol) {
// Construct names are not scoped by BLOCK in the standard, but many,
// but not all, compilers do treat them as if they were so scoped.
if (Symbol * inner{FindInScope(currScope(), *x)}) {
SayAlreadyDeclared(*x, *inner);
} else {
if (Symbol *
other{FindInScopeOrBlockConstructs(InclusiveScope(), x->source)}) {
SayWithDecl(*x, *other,
"The construct name '%s' should be distinct at the subprogram level"_port_en_US);
}
MakeSymbol(*x, MiscDetails{MiscDetails::Kind::ConstructName});
}
}
return true;
}
Expand Down
1 change: 1 addition & 0 deletions flang/test/Semantics/OpenACC/acc-branch.f90
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ program openacc_clause_validity
! Exit branches out of parallel construct, attached to an OpenACC parallel construct.
thisblk: BLOCK
fortname: if (.true.) then
!PORTABILITY: The construct name 'name1' should be distinct at the subprogram level
name1: do k = 1, N
!$acc parallel
!ERROR: EXIT to construct 'fortname' outside of PARALLEL construct is not allowed
Expand Down

0 comments on commit 594700c

Please sign in to comment.