diff --git a/flang/lib/Evaluate/check-expression.cpp b/flang/lib/Evaluate/check-expression.cpp --- a/flang/lib/Evaluate/check-expression.cpp +++ b/flang/lib/Evaluate/check-expression.cpp @@ -258,30 +258,29 @@ Result operator()(const CoarrayRef &) const { return "coindexed reference"; } Result operator()(const semantics::Symbol &symbol) const { - if (semantics::IsNamedConstant(symbol)) { + const auto &ultimate{symbol.GetUltimate()}; + if (semantics::IsNamedConstant(ultimate) || ultimate.owner().IsModule() || + ultimate.owner().IsSubmodule()) { return std::nullopt; - } else if (scope_.IsDerivedType() && IsVariableName(symbol)) { // C750, C754 + } else if (scope_.IsDerivedType() && + IsVariableName(ultimate)) { // C750, C754 return "derived type component or type parameter value not allowed to " "reference variable '"s + - symbol.name().ToString() + "'"; - } else if (IsDummy(symbol)) { - if (symbol.attrs().test(semantics::Attr::OPTIONAL)) { + ultimate.name().ToString() + "'"; + } else if (IsDummy(ultimate)) { + if (ultimate.attrs().test(semantics::Attr::OPTIONAL)) { return "reference to OPTIONAL dummy argument '"s + - symbol.name().ToString() + "'"; - } else if (symbol.attrs().test(semantics::Attr::INTENT_OUT)) { + ultimate.name().ToString() + "'"; + } else if (ultimate.attrs().test(semantics::Attr::INTENT_OUT)) { return "reference to INTENT(OUT) dummy argument '"s + - symbol.name().ToString() + "'"; - } else if (symbol.has()) { + ultimate.name().ToString() + "'"; + } else if (ultimate.has()) { return std::nullopt; } else { return "dummy procedure argument"; } - } else if (symbol.has() || - symbol.has() || - symbol.owner().kind() == semantics::Scope::Kind::Module) { - return std::nullopt; } else if (const auto *object{ - symbol.detailsIf()}) { + ultimate.detailsIf()}) { // TODO: what about EQUIVALENCE with data in COMMON? // TODO: does this work for blank COMMON? if (object->commonBlock()) { @@ -290,11 +289,11 @@ } for (const semantics::Scope *s{&scope_}; !s->IsGlobal();) { s = &s->parent(); - if (s == &symbol.owner()) { + if (s == &ultimate.owner()) { return std::nullopt; } } - return "reference to local entity '"s + symbol.name().ToString() + "'"; + return "reference to local entity '"s + ultimate.name().ToString() + "'"; } Result operator()(const Component &x) const { diff --git a/flang/test/Semantics/spec-expr.f90 b/flang/test/Semantics/spec-expr.f90 --- a/flang/test/Semantics/spec-expr.f90 +++ b/flang/test/Semantics/spec-expr.f90 @@ -173,3 +173,12 @@ real, dimension((param + 2)) :: realField end type dtype end subroutine s15 + +! Regression test: don't get confused by host association +subroutine s16(n) + integer :: n + contains + subroutine inner(r) + real, dimension(n) :: r + end subroutine +end subroutine s16