diff --git a/flang/lib/Semantics/check-declarations.cpp b/flang/lib/Semantics/check-declarations.cpp --- a/flang/lib/Semantics/check-declarations.cpp +++ b/flang/lib/Semantics/check-declarations.cpp @@ -88,6 +88,7 @@ void CheckGenericOps(const Scope &); bool CheckConflicting(const Symbol &, Attr, Attr); void WarnMissingFinal(const Symbol &); + void CheckSymbolType(const Symbol &); // C702 bool InPure() const { return innermostSymbol_ && IsPureProcedure(*innermostSymbol_); } @@ -494,15 +495,7 @@ void CheckHelper::CheckObjectEntity( const Symbol &symbol, const ObjectEntityDetails &details) { - if (!IsAllocatableOrPointer(symbol)) { // C702 - if (auto dyType{evaluate::DynamicType::From(symbol)}) { - if (dyType->HasDeferredTypeParameter()) { - messages_.Say( - "'%s' has a type %s with a deferred type parameter but is neither an allocatable or a pointer"_err_en_US, - symbol.name(), dyType->AsFortran()); - } - } - } + CheckSymbolType(symbol); CheckArraySpec(symbol, details.shape()); Check(details.shape()); Check(details.coshape()); @@ -801,6 +794,7 @@ void CheckHelper::CheckProcEntity( const Symbol &symbol, const ProcEntityDetails &details) { + CheckSymbolType(symbol); if (details.isDummy()) { if (!symbol.attrs().test(Attr::POINTER) && // C843 (symbol.attrs().test(Attr::INTENT_IN) || @@ -2337,6 +2331,18 @@ } } +void CheckHelper::CheckSymbolType(const Symbol &symbol) { + if (!IsAllocatableOrPointer(symbol)) { // C702 + if (auto dyType{evaluate::DynamicType::From(symbol)}) { + if (dyType->HasDeferredTypeParameter()) { + messages_.Say( + "'%s' has a type %s with a deferred type parameter but is neither an allocatable or a pointer"_err_en_US, + symbol.name(), dyType->AsFortran()); + } + } + } +} + void SubprogramMatchHelper::Check( const Symbol &symbol1, const Symbol &symbol2) { const auto details1{symbol1.get()}; diff --git a/flang/test/Semantics/resolve69.f90 b/flang/test/Semantics/resolve69.f90 --- a/flang/test/Semantics/resolve69.f90 +++ b/flang/test/Semantics/resolve69.f90 @@ -26,6 +26,16 @@ character(:) :: colonString2 !OK because of the allocatable attribute character(:), allocatable :: colonString3 +!ERROR: 'foo1' has a type CHARACTER(KIND=1,LEN=:) with a deferred type parameter but is neither an allocatable or a pointer + character(:), external :: foo1 +!ERROR: 'foo2' has a type CHARACTER(KIND=1,LEN=:) with a deferred type parameter but is neither an allocatable or a pointer + procedure(character(:)) :: foo2 + interface + function foo3() +!ERROR: 'foo3' has a type CHARACTER(KIND=1,LEN=:) with a deferred type parameter but is neither an allocatable or a pointer + character(:) foo3 + end function + end interface !ERROR: Must have INTEGER type, but is REAL(4) character(3.5) :: badParamValue @@ -75,6 +85,8 @@ implicit character(:)(f) end function +!Not errors. + Program d5 Type string(maxlen) Integer,Kind :: maxlen @@ -85,7 +97,6 @@ Print *,Trim(line%value) End Program -!Not errors. subroutine outer integer n contains