[flang-commits] [flang] 51d48a3 - [flang] Reimplement C1406 check as a warning
Peter Klausler via flang-commits
flang-commits at lists.llvm.org
Mon Mar 27 15:43:16 PDT 2023
Author: Peter Klausler
Date: 2023-03-27T15:43:09-07:00
New Revision: 51d48a3e6609c17299a16e8e823af6901be23c11
URL: https://github.com/llvm/llvm-project/commit/51d48a3e6609c17299a16e8e823af6901be23c11
DIFF: https://github.com/llvm/llvm-project/commit/51d48a3e6609c17299a16e8e823af6901be23c11.diff
LOG: [flang] Reimplement C1406 check as a warning
Constraint C1406 in Fortran 2018 prohibits the USE of the same module
name as both an intrinsic module and a non-intrinsic module in a scope.
The current check misinterprets the constraint as applying only to
explicitly INTRINSIC or NON_INTRINSIC module natures.
Change the check to also apply to non-explicit module natures, and
also downgrade it to a portability warning, since there is no ambiguity
and I suspect that we need to accept this usage when building f18's
own intrinsic modules.
Differential Revision: https://reviews.llvm.org/D146576
Added:
Modified:
flang/docs/Extensions.md
flang/lib/Semantics/resolve-names.cpp
flang/test/Semantics/modfile43.f90
Removed:
################################################################################
diff --git a/flang/docs/Extensions.md b/flang/docs/Extensions.md
index 4f68007418c51..7540283db5e8f 100644
--- a/flang/docs/Extensions.md
+++ b/flang/docs/Extensions.md
@@ -346,6 +346,9 @@ end
* User (non-intrinsic) `ELEMENTAL` procedures may not be passed as actual
arguments, in accordance with the standard; some Fortran compilers
permit such usage.
+* Constraint C1406, which prohibits the same module name from being used
+ in a scope for both an intrinsic and a non-intrinsic module, is implemented
+ as a portability warning only, not a hard error.
## Preprocessing behavior
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index ff5ae4af866dd..12370b08a3bfd 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -740,12 +740,12 @@ class ModuleVisitor : public virtual ScopeHandler {
bool BeginSubmodule(const parser::Name &, const parser::ParentIdentifier &);
void ApplyDefaultAccess();
Symbol &AddGenericUse(GenericDetails &, const SourceName &, const Symbol &);
- void AddAndCheckExplicitIntrinsicUse(SourceName, bool isIntrinsic);
+ void AddAndCheckModuleUse(SourceName, bool isIntrinsic);
void ClearUseRenames() { useRenames_.clear(); }
void ClearUseOnly() { useOnly_.clear(); }
- void ClearExplicitIntrinsicUses() {
- explicitIntrinsicUses_.clear();
- explicitNonIntrinsicUses_.clear();
+ void ClearModuleUses() {
+ intrinsicUses_.clear();
+ nonIntrinsicUses_.clear();
}
private:
@@ -759,10 +759,10 @@ class ModuleVisitor : public virtual ScopeHandler {
std::set<std::pair<SourceName, Scope *>> useRenames_;
// Names that have appeared in an ONLY clause of a USE statement
std::set<std::pair<SourceName, Scope *>> useOnly_;
- // Module names that have appeared in USE statements with explicit
- // INTRINSIC or NON_INTRINSIC keywords
- std::set<SourceName> explicitIntrinsicUses_;
- std::set<SourceName> explicitNonIntrinsicUses_;
+ // Intrinsic and non-intrinsic (explicit or not) module names that
+ // have appeared in USE statements; used for C1406 warnings.
+ std::set<SourceName> intrinsicUses_;
+ std::set<SourceName> nonIntrinsicUses_;
Symbol &SetAccess(const SourceName &, Attr attr, Symbol * = nullptr);
// A rename in a USE statement: local => use
@@ -2748,7 +2748,6 @@ bool ModuleVisitor::Pre(const parser::UseStmt &x) {
std::optional<bool> isIntrinsic;
if (x.nature) {
isIntrinsic = *x.nature == parser::UseStmt::ModuleNature::Intrinsic;
- AddAndCheckExplicitIntrinsicUse(x.moduleName.source, *isIntrinsic);
} else if (currScope().IsModule() && currScope().symbol() &&
currScope().symbol()->attrs().test(Attr::INTRINSIC)) {
// Intrinsic modules USE only other intrinsic modules
@@ -2758,6 +2757,8 @@ bool ModuleVisitor::Pre(const parser::UseStmt &x) {
if (!useModuleScope_) {
return false;
}
+ AddAndCheckModuleUse(x.moduleName.source,
+ useModuleScope_->parent().kind() == Scope::Kind::IntrinsicModules);
// use the name from this source file
useModuleScope_->symbol()->ReplaceName(x.moduleName.source);
return true;
@@ -3062,27 +3063,25 @@ Symbol &ModuleVisitor::AddGenericUse(
return newSymbol;
}
-// Enforce C1406
-void ModuleVisitor::AddAndCheckExplicitIntrinsicUse(
- SourceName name, bool isIntrinsic) {
+// Enforce C1406 as a warning
+void ModuleVisitor::AddAndCheckModuleUse(SourceName name, bool isIntrinsic) {
if (isIntrinsic) {
- if (auto iter{explicitNonIntrinsicUses_.find(name)};
- iter != explicitNonIntrinsicUses_.end()) {
+ if (auto iter{nonIntrinsicUses_.find(name)};
+ iter != nonIntrinsicUses_.end()) {
Say(name,
- "Cannot USE,INTRINSIC module '%s' in the same scope as USE,NON_INTRINSIC"_err_en_US,
+ "Should not USE the intrinsic module '%s' in the same scope as a USE of the non-intrinsic module"_port_en_US,
name)
.Attach(*iter, "Previous USE of '%s'"_en_US, *iter);
}
- explicitIntrinsicUses_.insert(name);
+ intrinsicUses_.insert(name);
} else {
- if (auto iter{explicitIntrinsicUses_.find(name)};
- iter != explicitIntrinsicUses_.end()) {
+ if (auto iter{intrinsicUses_.find(name)}; iter != intrinsicUses_.end()) {
Say(name,
- "Cannot USE,NON_INTRINSIC module '%s' in the same scope as USE,INTRINSIC"_err_en_US,
+ "Should not USE the non-intrinsic module '%s' in the same scope as a USE of the intrinsic module"_port_en_US,
name)
.Attach(*iter, "Previous USE of '%s'"_en_US, *iter);
}
- explicitNonIntrinsicUses_.insert(name);
+ nonIntrinsicUses_.insert(name);
}
}
@@ -7406,7 +7405,7 @@ bool ResolveNamesVisitor::Pre(const parser::SpecificationPart &x) {
Walk(useStmts);
ClearUseRenames();
ClearUseOnly();
- ClearExplicitIntrinsicUses();
+ ClearModuleUses();
Walk(importStmts);
Walk(implicitPart);
for (const auto &decl : decls) {
diff --git a/flang/test/Semantics/modfile43.f90 b/flang/test/Semantics/modfile43.f90
index d2bf5e750ad12..d908546128c50 100644
--- a/flang/test/Semantics/modfile43.f90
+++ b/flang/test/Semantics/modfile43.f90
@@ -5,7 +5,7 @@ module iso_fortran_env
end module
module m1
use, intrinsic :: iso_fortran_env, only: int32
- !ERROR: Cannot USE,NON_INTRINSIC module 'iso_fortran_env' in the same scope as USE,INTRINSIC
+ !PORTABILITY: Should not USE the non-intrinsic module 'iso_fortran_env' in the same scope as a USE of the intrinsic module
use, non_intrinsic :: iso_fortran_env, only: user_defined_123
end module
module m2
More information about the flang-commits
mailing list