Skip to content

Commit 0e1bb1d

Browse files
authored
[flang] Don't convert actual arguments when interface is implicit (#89795)
When the interface of a procedure is implicit at the point of call, don't perform actual argument type conversion to the types of the dummy arguments. This was inadvertently taking place in a case where the procedure has an implicit interface but was also defined in the same source file, so that its characteristics were known.
1 parent 83d0616 commit 0e1bb1d

File tree

3 files changed

+22
-4
lines changed

3 files changed

+22
-4
lines changed

flang/lib/Semantics/check-call.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1929,6 +1929,7 @@ bool CheckArguments(const characteristics::Procedure &proc,
19291929
bool explicitInterface{proc.HasExplicitInterface()};
19301930
evaluate::FoldingContext foldingContext{context.foldingContext()};
19311931
parser::ContextualMessages &messages{foldingContext.messages()};
1932+
bool allowArgumentConversions{true};
19321933
if (!explicitInterface || treatingExternalAsImplicit) {
19331934
parser::Messages buffer;
19341935
{
@@ -1945,11 +1946,12 @@ bool CheckArguments(const characteristics::Procedure &proc,
19451946
}
19461947
return false; // don't pile on
19471948
}
1949+
allowArgumentConversions = false;
19481950
}
19491951
if (explicitInterface) {
19501952
auto buffer{CheckExplicitInterface(proc, actuals, context, &scope,
1951-
intrinsic, /*allowArgumentConversions=*/true, /*extentErrors=*/true,
1952-
ignoreImplicitVsExplicit)};
1953+
intrinsic, allowArgumentConversions,
1954+
/*extentErrors=*/true, ignoreImplicitVsExplicit)};
19531955
if (!buffer.empty()) {
19541956
if (treatingExternalAsImplicit) {
19551957
if (auto *msg{messages.Say(

flang/lib/Semantics/expression.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2989,8 +2989,8 @@ void ExpressionAnalyzer::Analyze(const parser::CallStmt &callStmt) {
29892989
for (const auto &arg : actualArgList) {
29902990
analyzer.Analyze(arg, true /* is subroutine call */);
29912991
}
2992-
auto chevrons{AnalyzeChevrons(callStmt)};
2993-
if (!analyzer.fatalErrors() && chevrons) {
2992+
if (auto chevrons{AnalyzeChevrons(callStmt)};
2993+
chevrons && !analyzer.fatalErrors()) {
29942994
if (std::optional<CalleeAndArguments> callee{
29952995
GetCalleeAndArguments(std::get<parser::ProcedureDesignator>(call.t),
29962996
analyzer.GetActuals(), true /* subroutine */)}) {

flang/test/Semantics/arg-convert.f90

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
!RUN: %flang_fc1 -fdebug-unparse %s 2>&1 | FileCheck %s
2+
!Ensure that argument conversion does not take place when the procedure
3+
!interface is implicit at the point of call, even when the interface
4+
!is known due because the procedure's definition is in the same source file.
5+
6+
subroutine test
7+
!CHECK: warning: If the procedure's interface were explicit, this reference would be in error
8+
!CHECK: because: Actual argument type 'INTEGER(8)' is not compatible with dummy argument type 'INTEGER(4)'
9+
!CHECK: CALL samesourcefile((1_8))
10+
call sameSourceFile((1_8))
11+
!CHECK: CALL somewhereelse((2_8))
12+
call somewhereElse((2_8))
13+
end
14+
15+
subroutine sameSourceFile(n)
16+
end

0 commit comments

Comments
 (0)