@@ -2650,9 +2650,9 @@ static int ComputeCudaMatchingDistance(
2650
2650
// Handles a forward reference to a module function from what must
2651
2651
// be a specification expression. Return false if the symbol is
2652
2652
// an invalid forward reference.
2653
- bool ExpressionAnalyzer::ResolveForward (const Symbol &symbol) {
2653
+ const Symbol * ExpressionAnalyzer::ResolveForward (const Symbol &symbol) {
2654
2654
if (context_.HasError (symbol)) {
2655
- return false ;
2655
+ return nullptr ;
2656
2656
}
2657
2657
if (const auto *details{
2658
2658
symbol.detailsIf <semantics::SubprogramNameDetails>()}) {
@@ -2661,28 +2661,33 @@ bool ExpressionAnalyzer::ResolveForward(const Symbol &symbol) {
2661
2661
// checking a specification expression in a sibling module
2662
2662
// procedure. Resolve its names now so that its interface
2663
2663
// is known.
2664
+ const semantics::Scope &scope{symbol.owner ()};
2664
2665
semantics::ResolveSpecificationParts (context_, symbol);
2665
- if (symbol.has <semantics::SubprogramNameDetails>()) {
2666
+ const Symbol *resolved{nullptr };
2667
+ if (auto iter{scope.find (symbol.name ())}; iter != scope.cend ()) {
2668
+ resolved = &*iter->second ;
2669
+ }
2670
+ if (!resolved || resolved->has <semantics::SubprogramNameDetails>()) {
2666
2671
// When the symbol hasn't had its details updated, we must have
2667
2672
// already been in the process of resolving the function's
2668
2673
// specification part; but recursive function calls are not
2669
2674
// allowed in specification parts (10.1.11 para 5).
2670
2675
Say (" The module function '%s' may not be referenced recursively in a specification expression" _err_en_US,
2671
2676
symbol.name ());
2672
2677
context_.SetError (symbol);
2673
- return false ;
2674
2678
}
2679
+ return resolved;
2675
2680
} else if (inStmtFunctionDefinition_) {
2676
2681
semantics::ResolveSpecificationParts (context_, symbol);
2677
2682
CHECK (symbol.has <semantics::SubprogramDetails>());
2678
2683
} else { // 10.1.11 para 4
2679
2684
Say (" The internal function '%s' may not be referenced in a specification expression" _err_en_US,
2680
2685
symbol.name ());
2681
2686
context_.SetError (symbol);
2682
- return false ;
2687
+ return nullptr ;
2683
2688
}
2684
2689
}
2685
- return true ;
2690
+ return &symbol ;
2686
2691
}
2687
2692
2688
2693
// Resolve a call to a generic procedure with given actual arguments.
@@ -2709,20 +2714,21 @@ std::pair<const Symbol *, bool> ExpressionAnalyzer::ResolveGeneric(
2709
2714
}
2710
2715
if (const auto *details{ultimate.detailsIf <semantics::GenericDetails>()}) {
2711
2716
for (const Symbol &specific0 : details->specificProcs ()) {
2712
- const Symbol &specific {BypassGeneric (specific0)};
2713
- if (isSubroutine != !IsFunction (specific )) {
2717
+ const Symbol &specific1 {BypassGeneric (specific0)};
2718
+ if (isSubroutine != !IsFunction (specific1 )) {
2714
2719
continue ;
2715
2720
}
2716
- if (!ResolveForward (specific)) {
2721
+ const Symbol *specific{ResolveForward (specific1)};
2722
+ if (!specific) {
2717
2723
continue ;
2718
2724
}
2719
2725
if (std::optional<characteristics::Procedure> procedure{
2720
2726
characteristics::Procedure::Characterize (
2721
- ProcedureDesignator{specific}, context_.foldingContext (),
2727
+ ProcedureDesignator{* specific}, context_.foldingContext (),
2722
2728
/* emitError=*/ false )}) {
2723
2729
ActualArguments localActuals{actuals};
2724
- if (specific. has <semantics::ProcBindingDetails>()) {
2725
- if (!adjustActuals.value ()(specific, localActuals)) {
2730
+ if (specific-> has <semantics::ProcBindingDetails>()) {
2731
+ if (!adjustActuals.value ()(* specific, localActuals)) {
2726
2732
continue ;
2727
2733
}
2728
2734
}
@@ -2751,9 +2757,9 @@ std::pair<const Symbol *, bool> ExpressionAnalyzer::ResolveGeneric(
2751
2757
}
2752
2758
if (!procedure->IsElemental ()) {
2753
2759
// takes priority over elemental match
2754
- nonElemental = & specific;
2760
+ nonElemental = specific;
2755
2761
} else {
2756
- elemental = & specific;
2762
+ elemental = specific;
2757
2763
}
2758
2764
crtMatchingDistance = ComputeCudaMatchingDistance (
2759
2765
context_.languageFeatures (), *procedure, localActuals);
@@ -2866,7 +2872,12 @@ auto ExpressionAnalyzer::GetCalleeAndArguments(const parser::Name &name,
2866
2872
if (context_.HasError (symbol)) {
2867
2873
return std::nullopt; // also handles null symbol
2868
2874
}
2869
- const Symbol &ultimate{DEREF (symbol).GetUltimate ()};
2875
+ symbol = ResolveForward (*symbol);
2876
+ if (!symbol) {
2877
+ return std::nullopt;
2878
+ }
2879
+ name.symbol = const_cast <Symbol *>(symbol);
2880
+ const Symbol &ultimate{symbol->GetUltimate ()};
2870
2881
CheckForBadRecursion (name.source , ultimate);
2871
2882
bool dueToAmbiguity{false };
2872
2883
bool isGenericInterface{ultimate.has <semantics::GenericDetails>()};
0 commit comments