diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp --- a/flang/lib/Semantics/resolve-names.cpp +++ b/flang/lib/Semantics/resolve-names.cpp @@ -455,6 +455,8 @@ // TODO: Will return the scope of a FORALL or implied DO loop; is this ok? // If not, should call FindProgramUnitContaining() instead. Scope &InclusiveScope(); + // The enclosing scope, skipping derived types. + Scope &NonDerivedTypeScope(); // Create a new scope and push it on the scope stack. void PushScope(Scope::Kind kind, Symbol *symbol); @@ -1999,6 +2001,10 @@ DIE("inclusive scope not found"); } +Scope &ScopeHandler::NonDerivedTypeScope() { + return currScope_->IsDerivedType() ? currScope_->parent() : *currScope_; +} + void ScopeHandler::PushScope(Scope::Kind kind, Symbol *symbol) { PushScope(currScope().MakeScope(kind, symbol)); } @@ -3294,9 +3300,7 @@ bool DeclarationVisitor::Pre(const parser::AccessSpec &x) { Attr attr{AccessSpecToAttr(x)}; - const Scope &scope{ - currScope().IsDerivedType() ? currScope().parent() : currScope()}; - if (!scope.IsModule()) { // C817 + if (!NonDerivedTypeScope().IsModule()) { // C817 Say(currStmtSource().value(), "%s attribute may only appear in the specification part of a module"_err_en_US, EnumToString(attr)); @@ -4725,7 +4729,7 @@ std::optional DeclarationVisitor::ResolveDerivedType( const parser::Name &name) { - Symbol *symbol{FindSymbol(name)}; + Symbol *symbol{FindSymbol(NonDerivedTypeScope(), name)}; if (!symbol || symbol->has()) { if (allowForwardReferenceToDerivedType()) { if (!symbol) { @@ -5769,7 +5773,7 @@ void ResolveNamesVisitor::HandleProcedureName( Symbol::Flag flag, const parser::Name &name) { CHECK(flag == Symbol::Flag::Function || flag == Symbol::Flag::Subroutine); - auto *symbol{FindSymbol(name)}; + auto *symbol{FindSymbol(NonDerivedTypeScope(), name)}; if (!symbol) { if (context().intrinsics().IsIntrinsic(name.source.ToString())) { symbol = diff --git a/flang/test/Semantics/resolve92.f90 b/flang/test/Semantics/resolve92.f90 new file mode 100644 --- /dev/null +++ b/flang/test/Semantics/resolve92.f90 @@ -0,0 +1,16 @@ +! RUN: %S/test_errors.sh %s %t %f18 + +module m + implicit none + type t + integer :: n + end type + type t2 + ! t and t2 must be resolved to types in m, not components in t2 + type(t) :: t(10) = t(1) + type(t) :: x = t(1) + integer :: t2 + type(t2), pointer :: p + end type +end +