diff --git a/flang/lib/Semantics/check-declarations.cpp b/flang/lib/Semantics/check-declarations.cpp index 26efa288b5aeee..c5d0d0fcbbacff 100644 --- a/flang/lib/Semantics/check-declarations.cpp +++ b/flang/lib/Semantics/check-declarations.cpp @@ -1357,6 +1357,15 @@ bool CheckHelper::IsResultOkToDiffer(const FunctionResult &result) { void CheckHelper::CheckSubprogram( const Symbol &symbol, const SubprogramDetails &details) { + // Evaluate a procedure definition's characteristics to flush out + // any errors that analysis might expose, in case this subprogram hasn't + // had any calls in this compilation unit that would have validated them. + if (!context_.HasError(symbol) && !details.isDummy() && + !details.isInterface() && !details.stmtFunction()) { + if (!Procedure::Characterize(symbol, foldingContext_)) { + context_.SetError(symbol); + } + } if (const Symbol *iface{FindSeparateModuleSubprogramInterface(&symbol)}) { SubprogramMatchHelper{*this}.Check(symbol, *iface); } diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp index e2875081b732c7..5626f2a8be97aa 100644 --- a/flang/lib/Semantics/resolve-names.cpp +++ b/flang/lib/Semantics/resolve-names.cpp @@ -5013,8 +5013,7 @@ bool DeclarationVisitor::HasCycle( if (procsInCycle.count(*interface) > 0) { for (const auto &procInCycle : procsInCycle) { Say(procInCycle->name(), - "The interface for procedure '%s' is recursively " - "defined"_err_en_US, + "The interface for procedure '%s' is recursively defined"_err_en_US, procInCycle->name()); context().SetError(*procInCycle); } diff --git a/flang/test/Semantics/entry01.f90 b/flang/test/Semantics/entry01.f90 index 970cd109921a15..765b18c2e81a8a 100644 --- a/flang/test/Semantics/entry01.f90 +++ b/flang/test/Semantics/entry01.f90 @@ -83,6 +83,7 @@ function ifunc() !ERROR: 'ibad1' is already declared in this scoping unit entry ibad1() result(ibad1res) ! C1570 !ERROR: 'ibad2' is already declared in this scoping unit + !ERROR: Procedure 'ibad2' is referenced before being sufficiently defined in a context where it must be so entry ibad2() !ERROR: ENTRY in a function may not have an alternate return dummy argument entry ibadalt(*) ! C1573 @@ -91,6 +92,7 @@ function ifunc() entry iok() !ERROR: Explicit RESULT('iok') of function 'isameres2' cannot have the same name as a distinct ENTRY into the same scope entry isameres2() result(iok) ! C1574 + !ERROR: Procedure 'iok2' is referenced before being sufficiently defined in a context where it must be so !ERROR: Explicit RESULT('iok2') of function 'isameres3' cannot have the same name as a distinct ENTRY into the same scope entry isameres3() result(iok2) ! C1574 !ERROR: 'iok2' is already declared in this scoping unit diff --git a/flang/test/Semantics/resolve102.f90 b/flang/test/Semantics/resolve102.f90 index 8f6e2246a57e79..33cf6fa245ea49 100644 --- a/flang/test/Semantics/resolve102.f90 +++ b/flang/test/Semantics/resolve102.f90 @@ -4,17 +4,12 @@ !ERROR: Procedure 'sub' is recursively defined. Procedures in the cycle: 'sub', 'p2' subroutine sub(p2) PROCEDURE(sub) :: p2 - - call sub() end subroutine subroutine circular - !ERROR: Procedure 'p' is recursively defined. Procedures in the cycle: 'p', 'sub', 'p2' procedure(sub) :: p - - call p(sub) - contains + !ERROR: Procedure 'sub' is recursively defined. Procedures in the cycle: 'p', 'sub', 'p2' subroutine sub(p2) procedure(p) :: p2 end subroutine @@ -41,11 +36,10 @@ subroutine sub(p2) subroutine mutual Procedure(sub1) :: p - - Call p(sub) - contains !ERROR: Procedure 'sub1' is recursively defined. Procedures in the cycle: 'p', 'sub1', 'arg' + !ERROR: Procedure 'sub1' is recursively defined. Procedures in the cycle: 'sub1', 'arg', 'sub', 'p2' + !ERROR: Procedure 'sub1' is recursively defined. Procedures in the cycle: 'sub1', 'arg' Subroutine sub1(arg) procedure(sub1) :: arg End Subroutine @@ -57,15 +51,14 @@ Subroutine sub(p2) subroutine mutual1 Procedure(sub1) :: p - - Call p(sub) - contains !ERROR: Procedure 'sub1' is recursively defined. Procedures in the cycle: 'p', 'sub1', 'arg', 'sub', 'p2' + !ERROR: Procedure 'sub1' is recursively defined. Procedures in the cycle: 'sub1', 'arg', 'sub', 'p2' Subroutine sub1(arg) procedure(sub) :: arg End Subroutine + !ERROR: Procedure 'sub' is recursively defined. Procedures in the cycle: 'sub1', 'arg', 'sub', 'p2' Subroutine sub(p2) Procedure(sub1) :: p2 End Subroutine @@ -76,8 +69,6 @@ subroutine twoCycle !ERROR: The interface for procedure 'p2' is recursively defined procedure(p1) p2 procedure(p2) p1 - call p1 - call p2 end subroutine subroutine threeCycle @@ -87,9 +78,6 @@ subroutine threeCycle !ERROR: The interface for procedure 'p3' is recursively defined procedure(p2) p3 procedure(p3) p1 - call p1 - call p2 - call p3 end subroutine module mutualSpecExprs @@ -118,4 +106,3 @@ function ifunc(x) ifunc = x end end -