[flang] Allow module, submodule, and program names to be used as local identifiers. Check for USE of m in m.

Original-commit: flang-compiler/f18@9abfd9e450
Reviewed-on: https://github.com/flang-compiler/f18/pull/737
Tree-same-pre-rewrite: false
This commit is contained in:
peter klausler 2019-09-11 12:30:24 -07:00
parent 2deefe166c
commit 62e4acf232
3 changed files with 29 additions and 4 deletions

View File

@ -1653,7 +1653,11 @@ void ScopeHandler::PushScope(Scope &scope) {
if (kind != Scope::Kind::Block) {
ImplicitRulesVisitor::BeginScope(scope);
}
if (!currScope_->IsDerivedType()) {
// The name of a module or submodule cannot be "used" in its scope,
// as we read 19.3.1(2), so we allow the name to be used as a local
// identifier in the module or submodule too. Same with programs.
if (!currScope_->IsDerivedType() && kind != Scope::Kind::Module &&
kind != Scope::Kind::MainProgram) {
if (auto *symbol{scope.symbol()}) {
// Create a dummy symbol so we can't create another one with the same
// name. It might already be there if we previously pushed the scope.
@ -2086,7 +2090,7 @@ void ModuleVisitor::BeginModule(const parser::Name &name, bool isSubmodule) {
// If an error occurs, report it and return nullptr.
Scope *ModuleVisitor::FindModule(const parser::Name &name, Scope *ancestor) {
ModFileReader reader{context()};
auto *scope{reader.Read(name.source, ancestor)};
Scope *scope{reader.Read(name.source, ancestor)};
if (!scope) {
return nullptr;
}
@ -2094,6 +2098,9 @@ Scope *ModuleVisitor::FindModule(const parser::Name &name, Scope *ancestor) {
Say(name, "'%s' is not a module"_err_en_US);
return nullptr;
}
if (DoesScopeContain(scope, currScope())) {
Say(name, "Module '%s' cannot USE itself."_err_en_US);
}
Resolve(name, scope->symbol());
return scope;
}

View File

@ -13,9 +13,24 @@
! limitations under the License.
program p
!ERROR: 'p' is already declared in this scoping unit
integer p
integer :: p ! this is ok
end
module m
integer :: m ! this is ok
end
submodule(m) sm
integer :: sm ! this is ok
end
module m2
type :: t
end type
interface
subroutine s
!ERROR: Module 'm2' cannot USE itself.
use m2, only: t
end subroutine
end interface
end module
subroutine s
!ERROR: 's' is already declared in this scoping unit
integer :: s

View File

@ -48,6 +48,9 @@ module m
type :: bad3
end type
type :: m ! the name of a module can be used as a local identifier
end type m
external :: a, b, c, d
!ERROR: EXTERNAL attribute not allowed on 'm'
external :: m