Skip to content

Commit 8b7a90b

Browse files
authored
[flang] Accept proc ptr function result as actual argument without IN… (#128771)
…TENT A dummy procedure pointer with no INTENT attribute may associate with an actual argument that is the result of a reference to a function that returns a procedure pointer, we think. Fixes #126950.
1 parent e1ba1be commit 8b7a90b

File tree

4 files changed

+35
-27
lines changed

4 files changed

+35
-27
lines changed

flang/lib/Semantics/check-call.cpp

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1049,8 +1049,8 @@ static void CheckProcedureArg(evaluate::ActualArgument &arg,
10491049
SemanticsContext &context, bool ignoreImplicitVsExplicit) {
10501050
evaluate::FoldingContext &foldingContext{context.foldingContext()};
10511051
parser::ContextualMessages &messages{foldingContext.messages()};
1052-
auto restorer{
1053-
messages.SetLocation(arg.sourceLocation().value_or(messages.at()))};
1052+
parser::CharBlock location{arg.sourceLocation().value_or(messages.at())};
1053+
auto restorer{messages.SetLocation(location)};
10541054
const characteristics::Procedure &interface { dummy.procedure.value() };
10551055
if (const auto *expr{arg.UnwrapExpr()}) {
10561056
bool dummyIsPointer{
@@ -1175,22 +1175,30 @@ static void CheckProcedureArg(evaluate::ActualArgument &arg,
11751175
dummyName);
11761176
}
11771177
}
1178-
if (dummyIsPointer && dummy.intent != common::Intent::In) {
1179-
const Symbol *last{GetLastSymbol(*expr)};
1180-
if (last && IsProcedurePointer(*last)) {
1181-
if (dummy.intent != common::Intent::Default &&
1182-
IsIntentIn(last->GetUltimate())) { // 19.6.8
1183-
messages.Say(
1184-
"Actual argument associated with procedure pointer %s may not be INTENT(IN)"_err_en_US,
1185-
dummyName);
1186-
}
1187-
} else if (!(dummy.intent == common::Intent::Default &&
1188-
IsNullProcedurePointer(*expr))) {
1189-
// 15.5.2.9(5) -- dummy procedure POINTER
1190-
// Interface compatibility has already been checked above
1178+
if (dummyIsPointer) {
1179+
if (dummy.intent == common::Intent::In) {
1180+
// need not be definable, can be a target
1181+
} else if (!IsProcedurePointer(*expr)) {
11911182
messages.Say(
1192-
"Actual argument associated with procedure pointer %s must be a pointer unless INTENT(IN)"_err_en_US,
1183+
"Actual argument associated with procedure pointer %s is not a procedure pointer"_err_en_US,
11931184
dummyName);
1185+
} else if (dummy.intent == common::Intent::Default) {
1186+
// ok, needs to be definable only if defined at run time
1187+
} else {
1188+
DefinabilityFlags flags{DefinabilityFlag::PointerDefinition};
1189+
if (dummy.intent != common::Intent::Out) {
1190+
flags.set(DefinabilityFlag::DoNotNoteDefinition);
1191+
}
1192+
if (auto whyNot{WhyNotDefinable(
1193+
location, context.FindScope(location), flags, *expr)}) {
1194+
if (auto *msg{messages.Say(
1195+
"Actual argument associated with INTENT(%s) procedure pointer %s is not definable"_err_en_US,
1196+
dummy.intent == common::Intent::Out ? "OUT" : "IN OUT",
1197+
dummyName)}) {
1198+
msg->Attach(
1199+
std::move(whyNot->set_severity(parser::Severity::Because)));
1200+
}
1201+
}
11941202
}
11951203
}
11961204
} else {

flang/test/Semantics/call09.f90

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -82,27 +82,26 @@ subroutine test1 ! 15.5.2.9(5)
8282
call s01(null(intPtr))
8383
!ERROR: Actual argument associated with procedure dummy argument 'p=' is typeless
8484
call s01(B"0101")
85-
!ERROR: Actual argument associated with procedure pointer dummy argument 'p=' must be a pointer unless INTENT(IN)
85+
!ERROR: Actual argument associated with procedure pointer dummy argument 'p=' is not a procedure pointer
8686
call s02(realfunc)
8787
call s02(p) ! ok
8888
!ERROR: Actual procedure argument has interface incompatible with dummy argument 'p=': function results have distinct types: REAL(4) vs INTEGER(4)
8989
call s02(ip)
90-
!ERROR: Actual argument associated with procedure pointer dummy argument 'p=' must be a pointer unless INTENT(IN)
91-
call s02(procptr())
90+
call s02(procptr()) ! believed to be ok
9291
call s02(null()) ! ok
93-
!ERROR: Actual argument associated with procedure pointer dummy argument 'p=' must be a pointer unless INTENT(IN)
92+
!ERROR: Actual argument associated with INTENT(IN OUT) procedure pointer dummy argument 'p=' is not definable
93+
!BECAUSE: 'NULL()' is a null pointer
9494
call s05(null())
95-
!ERROR: Actual argument associated with procedure pointer dummy argument 'p=' must be a pointer unless INTENT(IN)
95+
!ERROR: Actual argument associated with procedure pointer dummy argument 'p=' is not a procedure pointer
9696
call s02(sin)
97-
!ERROR: Actual argument associated with procedure pointer dummy argument 'p=' must be a pointer unless INTENT(IN)
97+
!ERROR: Actual argument associated with procedure pointer dummy argument 'p=' is not a procedure pointer
9898
call s02b(realfunc)
9999
call s02b(p) ! ok
100100
!ERROR: Actual argument function associated with procedure dummy argument 'p=' is not compatible: function results have distinct types: REAL(4) vs INTEGER(4)
101101
call s02b(ip)
102-
!ERROR: Actual argument associated with procedure pointer dummy argument 'p=' must be a pointer unless INTENT(IN)
103-
call s02b(procptr())
102+
call s02b(procptr()) ! believed to be ok
104103
call s02b(null())
105-
!ERROR: Actual argument associated with procedure pointer dummy argument 'p=' must be a pointer unless INTENT(IN)
104+
!ERROR: Actual argument associated with procedure pointer dummy argument 'p=' is not a procedure pointer
106105
call s02b(sin)
107106
end subroutine
108107

flang/test/Semantics/call24.f90

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ subroutine test()
3939
!ERROR: References to the procedure 'bar' require an explicit interface
4040
!BECAUSE: a dummy procedure is optional or a pointer
4141
!WARNING: If the procedure's interface were explicit, this reference would be in error
42-
!BECAUSE: Actual argument associated with procedure pointer dummy argument 'a_pointer=' must be a pointer unless INTENT(IN)
42+
!BECAUSE: Actual argument associated with procedure pointer dummy argument 'a_pointer=' is not a procedure pointer
4343
call bar(sin)
4444

4545
!ERROR: References to the procedure 'baz' require an explicit interface

flang/test/Semantics/definable01.f90

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,8 @@ subroutine test3(objp, procp)
7777
!CHECK: error: Actual argument associated with INTENT(IN OUT) dummy argument 'op=' is not definable
7878
!CHECK: because: 'objp' is an INTENT(IN) dummy argument
7979
call test3a(objp)
80-
!CHECK: error: Actual argument associated with procedure pointer dummy argument 'pp=' may not be INTENT(IN)
80+
!CHECK: error: Actual argument associated with INTENT(IN OUT) procedure pointer dummy argument 'pp=' is not definable
81+
!CHECK: because: 'procp' is an INTENT(IN) dummy argument
8182
call test3b(procp)
8283
end subroutine
8384
subroutine test3a(op)

0 commit comments

Comments
 (0)