[flang] Fix confusing explanatory error message (#187341)

When a reference to a generic procedure fails, the compiler explains why
each of the generic's specific procedures failed to match the actual
arguments. This code had a subtle bug: adjustments to the actual
arguments made for interface checking for earlier specific procedures
would persist and affect the checks for later specific procedures.
This commit is contained in:
Peter Klausler 2026-03-18 17:04:47 -05:00 committed by GitHub
parent 8e06210559
commit ca07ca0314
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 22 additions and 9 deletions

View file

@ -377,7 +377,7 @@ private:
const AdjustActuals &, bool isSubroutine, SymbolVector &&tried,
bool mightBeStructureConstructor = false);
void EmitGenericResolutionError(const Symbol &, bool dueToNullActuals,
bool isSubroutine, ActualArguments &, const SymbolVector &,
bool isSubroutine, const ActualArguments &, const SymbolVector &,
const AdjustActuals &);
const Symbol &AccessSpecific(
const Symbol &originalGeneric, const Symbol &specific);

View file

@ -3144,7 +3144,7 @@ const Symbol &ExpressionAnalyzer::AccessSpecific(
}
void ExpressionAnalyzer::EmitGenericResolutionError(const Symbol &symbol,
bool dueToAmbiguity, bool isSubroutine, ActualArguments &arguments,
bool dueToAmbiguity, bool isSubroutine, const ActualArguments &arguments,
const SymbolVector &tried, const AdjustActuals &adjustment) {
if (auto *msg{Say(dueToAmbiguity
? "The actual arguments to the generic procedure '%s' matched multiple specific procedures, perhaps due to use of NULL() without MOLD= or an actual procedure with an implicit interface"_err_en_US
@ -3158,16 +3158,12 @@ void ExpressionAnalyzer::EmitGenericResolutionError(const Symbol &symbol,
if (auto procChars{characteristics::Procedure::Characterize(
specific, GetFoldingContext())}) {
if (procChars->HasExplicitInterface()) {
ActualArguments *actuals{&arguments};
ActualArguments adjustedActuals;
ActualArguments adjusted{arguments};
if (specific.has<semantics::ProcBindingDetails>() &&
adjustment.has_value()) {
adjustedActuals = arguments;
if ((*adjustment)(specific, adjustedActuals)) {
actuals = &adjustedActuals;
}
(*adjustment)(specific, adjusted);
}
auto reasons{semantics::CheckExplicitInterface(*procChars, *actuals,
auto reasons{semantics::CheckExplicitInterface(*procChars, adjusted,
context_, /*scope=*/nullptr, /*intrinsic=*/nullptr,
/*allocActualArgumentConversions=*/false,
/*extentErrors=*/false,

View file

@ -0,0 +1,17 @@
!RUN: not %flang_fc1 -fsyntax-only %s 2>&1 | FileCheck %s
module m
generic :: gen => spec2, spec1
contains
subroutine spec2(a,b)
real, intent(in) :: a(*), b(*)
end
subroutine spec1(a)
real, intent(in) :: a(:)
end
subroutine test(a)
real, intent(in) :: a(*)
!CHECK: Dummy argument 'b=' (#2) is not OPTIONAL and is not associated with an actual argument in this procedure reference
!CHECK: Assumed-size array may not be associated with assumed-shape dummy argument 'a='
call gen(a)
end
end