[flang-commits] [flang] 2ce7432 - [flang] Enabling automatic declaration of names in SHARED locality-spec's
Peter Steinfeld via flang-commits
flang-commits at lists.llvm.org
Thu Apr 9 08:15:35 PDT 2020
Author: Peter Steinfeld
Date: 2019-07-10T12:53:55-07:00
New Revision: 2ce7432bb8b353eb011a15645187b5bdeda8039b
URL: https://github.com/llvm/llvm-project/commit/2ce7432bb8b353eb011a15645187b5bdeda8039b
DIFF: https://github.com/llvm/llvm-project/commit/2ce7432bb8b353eb011a15645187b5bdeda8039b.diff
LOG: [flang] Enabling automatic declaration of names in SHARED locality-spec's
Prior to this change, the compiler issued an error message when a name in a
SHARED locality-spec had not been declared explicitly in an enclosing scope.
Presumably, this was done to enforce constraint C1124. This constraint states
that "A variable-name in a locality-spec shall be the name of a variable in the
innermost executable construct or scoping unit that includes the DO CONCURRENT
statement". For LOCAL and LOCAL_INIT locality-spec's, we were automatically
creating a local variable in the situation where one had not been explicitly
declared rather than issuing an error message.
The only compiler I could find that implements the SHARED locality-spec was the
PGI compiler, which automatically creates a variable and does not emit an error
message. Also, @vdonaldson said that he had consulted with a member of the
Fortran standards committee who said that the correct thing was to create a
variable if necessary.
This change has the compiler creating a variable in the enclosing scope of a DO
CONCURRENT statement if necessary. I also changed a test to adapt to the new
behavior. I also consolidated the semantic checking for the constraints
associated with all of the locality-spec's.
Original-commit: flang-compiler/f18 at d9253a76fcbc49df11c017557b365dfeed7c2b3b
Reviewed-on: https://github.com/flang-compiler/f18/pull/551
Tree-same-pre-rewrite: false
Added:
Modified:
flang/lib/semantics/resolve-names.cc
flang/test/semantics/resolve35.f90
Removed:
################################################################################
diff --git a/flang/lib/semantics/resolve-names.cc b/flang/lib/semantics/resolve-names.cc
index 6313e7469d3d..fa742d563288 100644
--- a/flang/lib/semantics/resolve-names.cc
+++ b/flang/lib/semantics/resolve-names.cc
@@ -746,6 +746,8 @@ class DeclarationVisitor : public ArraySpecVisitor,
bool BeginDecl();
void EndDecl();
Symbol &DeclareObjectEntity(const parser::Name &, Attrs);
+ // Make sure that there's an entity in an enclosing scope called Name
+ Symbol *EnsureEnclosingEntity(const parser::Name &);
// Declare a LOCAL/LOCAL_INIT entity. If there isn't a type specified
// it comes from the entity in the containing scope, or implicit rules.
// Return pointer to the new symbol, or nullptr on error.
@@ -772,6 +774,7 @@ class DeclarationVisitor : public ArraySpecVisitor,
const parser::Name *ResolveDataRef(const parser::DataRef &);
const parser::Name *ResolveVariable(const parser::Variable &);
const parser::Name *ResolveName(const parser::Name &);
+ bool PassesSharedLocalityChecks(const parser::Name &name, Symbol &symbol);
private:
// The attribute corresponding to the statement containing an ObjectDecl
@@ -3725,12 +3728,26 @@ bool DeclarationVisitor::HandleUnrestrictedSpecificIntrinsicFunction(
}
}
-bool DeclarationVisitor::PassesLocalityChecks(
+// Checks for all locality-specs: LOCAL, LOCAL_INIT, and SHARED
+bool DeclarationVisitor::PassesSharedLocalityChecks(
const parser::Name &name, Symbol &symbol) {
if (!IsVariableName(symbol)) {
SayLocalMustBeVariable(name, symbol); // C1124
return false;
}
+ if (symbol.owner() == currScope()) { // C1125 and C1126
+ SayAlreadyDeclared(name, symbol);
+ return false;
+ }
+ return true;
+}
+
+// Checks for locality-specs LOCAL and LOCAL_INIT
+bool DeclarationVisitor::PassesLocalityChecks(
+ const parser::Name &name, Symbol &symbol) {
+ if (!PassesSharedLocalityChecks(name, symbol)) {
+ return false;
+ }
if (IsAllocatable(symbol)) { // C1128
SayWithDecl(name, symbol,
"ALLOCATABLE variable '%s' not allowed in a locality-spec"_err_en_US);
@@ -3770,35 +3787,33 @@ bool DeclarationVisitor::PassesLocalityChecks(
"Assumed size array '%s' not allowed in a locality-spec"_err_en_US);
return false;
}
- if (symbol.owner() == currScope()) { // C1125 and C1126
- SayAlreadyDeclared(name, symbol);
- return false;
- }
// TODO: Check to see if the name can appear in a variable definition context
return true;
}
-Symbol *DeclarationVisitor::DeclareLocalEntity(const parser::Name &name) {
+Symbol *DeclarationVisitor::EnsureEnclosingEntity(const parser::Name &name) {
Symbol *prev{FindSymbol(name)};
- bool implicit{false};
if (prev == nullptr) {
// Declare the name as an object in the enclosing scope so that
// the name can't be repurposed there later as something else.
prev = &MakeSymbol(InclusiveScope(), name.source, Attrs{});
ConvertToObjectEntity(*prev);
ApplyImplicitRules(*prev);
- implicit = true;
}
+ return prev;
+}
+
+Symbol *DeclarationVisitor::DeclareLocalEntity(const parser::Name &name) {
+ Symbol *prev{EnsureEnclosingEntity(name)};
if (!PassesLocalityChecks(name, *prev)) {
return nullptr;
}
name.symbol = nullptr;
Symbol &symbol{DeclareEntity<ObjectEntityDetails>(name, {})};
if (auto *type{prev->GetType()}) {
- if (implicit) {
- ApplyImplicitRules(symbol);
- } else {
- symbol.SetType(*type);
+ symbol.SetType(*type);
+ if (prev->test(Symbol::Flag::Implicit)) {
+ symbol.set(Symbol::Flag::Implicit);
}
}
return &symbol;
@@ -4091,16 +4106,8 @@ bool ConstructVisitor::Pre(const parser::LocalitySpec::LocalInit &x) {
bool ConstructVisitor::Pre(const parser::LocalitySpec::Shared &x) {
for (const auto &name : x.v) {
- Symbol *prev{FindSymbol(name)};
- if (!prev) {
- Say(name, "Variable '%s' not found"_err_en_US);
- context().SetError(
- MakeSymbol(name, ObjectEntityDetails{EntityDetails{}}));
- } else if (prev->owner() == currScope()) {
- SayAlreadyDeclared(name, *prev); // C1125 and C1126
- } else if (!IsVariableName(*prev)) {
- SayLocalMustBeVariable(name, *prev); // C1124
- } else {
+ Symbol *prev{EnsureEnclosingEntity(name)};
+ if (PassesSharedLocalityChecks(name, *prev)) {
auto &symbol{MakeSymbol(name, HostAssocDetails{*prev})};
symbol.set(Symbol::Flag::LocalityShared);
name.symbol = &symbol; // override resolution to parent
diff --git a/flang/test/semantics/resolve35.f90 b/flang/test/semantics/resolve35.f90
index d5433ab7fbb1..c2ec8cc8811d 100644
--- a/flang/test/semantics/resolve35.f90
+++ b/flang/test/semantics/resolve35.f90
@@ -88,7 +88,6 @@ subroutine s7
do concurrent(integer::i=1:5) local(j, i) &
!ERROR: 'j' is already declared in this scoping unit
local_init(k, j) &
- !ERROR: Variable 'a' not found
shared(a)
a(i) = j + 1
end do
More information about the flang-commits
mailing list