File tree Expand file tree Collapse file tree 4 files changed +83
-1
lines changed Expand file tree Collapse file tree 4 files changed +83
-1
lines changed Original file line number Diff line number Diff line change @@ -1416,6 +1416,8 @@ common::IgnoreTKRSet GetIgnoreTKR(const Symbol &);
1416
1416
1417
1417
std::optional<int > GetDummyArgumentNumber (const Symbol *);
1418
1418
1419
+ const Symbol *FindAncestorModuleProcedure (const Symbol *symInSubmodule);
1420
+
1419
1421
} // namespace Fortran::semantics
1420
1422
1421
1423
#endif // FORTRAN_EVALUATE_TOOLS_H_
Original file line number Diff line number Diff line change @@ -731,11 +731,16 @@ static std::optional<Procedure> CharacterizeProcedure(
731
731
return std::optional<Procedure>{};
732
732
}
733
733
},
734
- [&](const semantics::EntityDetails &) {
734
+ [&](const semantics::EntityDetails &x ) {
735
735
CheckForNested (symbol);
736
736
return std::optional<Procedure>{};
737
737
},
738
738
[&](const semantics::SubprogramNameDetails &) {
739
+ if (const semantics::Symbol *
740
+ ancestor{FindAncestorModuleProcedure (&symbol)}) {
741
+ return CharacterizeProcedure (
742
+ *ancestor, context, seenProcs, emitError);
743
+ }
739
744
CheckForNested (symbol);
740
745
return std::optional<Procedure>{};
741
746
},
Original file line number Diff line number Diff line change @@ -1990,4 +1990,37 @@ std::optional<int> GetDummyArgumentNumber(const Symbol *symbol) {
1990
1990
return std::nullopt;
1991
1991
}
1992
1992
1993
+ // Given a symbol that is a SubprogramNameDetails in a submodule, try to
1994
+ // find its interface definition in its module or ancestor submodule.
1995
+ const Symbol *FindAncestorModuleProcedure (const Symbol *symInSubmodule) {
1996
+ if (symInSubmodule && symInSubmodule->owner ().IsSubmodule ()) {
1997
+ if (const auto *nameDetails{
1998
+ symInSubmodule->detailsIf <semantics::SubprogramNameDetails>()};
1999
+ nameDetails &&
2000
+ nameDetails->kind () == semantics::SubprogramKind::Module) {
2001
+ const Symbol *next{symInSubmodule->owner ().symbol ()};
2002
+ while (const Symbol * submodSym{next}) {
2003
+ next = nullptr ;
2004
+ if (const auto *modDetails{
2005
+ submodSym->detailsIf <semantics::ModuleDetails>()};
2006
+ modDetails && modDetails->isSubmodule () && modDetails->scope ()) {
2007
+ if (const semantics::Scope & parent{modDetails->scope ()->parent ()};
2008
+ parent.IsSubmodule () || parent.IsModule ()) {
2009
+ if (auto iter{parent.find (symInSubmodule->name ())};
2010
+ iter != parent.end ()) {
2011
+ const Symbol &proc{iter->second ->GetUltimate ()};
2012
+ if (IsProcedure (proc)) {
2013
+ return &proc;
2014
+ }
2015
+ } else if (parent.IsSubmodule ()) {
2016
+ next = parent.symbol ();
2017
+ }
2018
+ }
2019
+ }
2020
+ }
2021
+ }
2022
+ }
2023
+ return nullptr ;
2024
+ }
2025
+
1993
2026
} // namespace Fortran::semantics
Original file line number Diff line number Diff line change
1
+ ! RUN: %flang -fsyntax-only %s 2>&1 | FileCheck --allow-empty %s
2
+ ! Ensure no bogus error messages about insufficiently defined procedures
3
+ ! CHECK-NOT: error
4
+
5
+ module m
6
+ interface
7
+ module subroutine smp1 (a1 )
8
+ end
9
+ end interface
10
+ end
11
+
12
+ submodule(m) sm1
13
+ interface
14
+ module subroutine smp2 (a1 ,a2 )
15
+ end
16
+ end interface
17
+ end
18
+
19
+ submodule(m:sm1) sm2
20
+ interface generic
21
+ procedure smp1
22
+ procedure smp2
23
+ module subroutine smp3 (a1 ,a2 ,a3 )
24
+ end
25
+ end interface
26
+ contains
27
+ subroutine local1
28
+ call generic(0 .)
29
+ call generic(0 ., 1 .)
30
+ call generic(0 ., 1 ., 2 .)
31
+ end
32
+ subroutine local2 (a1 ,a2 ,a3 )
33
+ end
34
+ module procedure smp1
35
+ end
36
+ module subroutine smp2 (a1 ,a2 )
37
+ end
38
+ module subroutine smp3 (a1 ,a2 ,a3 )
39
+ end
40
+ end
41
+
42
+
You can’t perform that action at this time.
0 commit comments