Skip to content

Commit 13dd403

Browse files
committed
[flang] Catch coindexed procedure pointer/binding references
A procedure designator cannot be coindexed, except for cases in which the coindexing doesn't matter (i.e. a binding that can't be overridden).
1 parent f6e8366 commit 13dd403

File tree

3 files changed

+56
-1
lines changed

3 files changed

+56
-1
lines changed

flang/include/flang/Evaluate/tools.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -464,9 +464,13 @@ struct ExtractCoindexedObjectHelper {
464464
}
465465
};
466466

467+
static inline std::optional<CoarrayRef> ExtractCoarrayRef(const DataRef &x) {
468+
return ExtractCoindexedObjectHelper{}(x);
469+
}
470+
467471
template <typename A> std::optional<CoarrayRef> ExtractCoarrayRef(const A &x) {
468472
if (auto dataRef{ExtractDataRef(x, true)}) {
469-
return ExtractCoindexedObjectHelper{}(*dataRef);
473+
return ExtractCoarrayRef(*dataRef);
470474
} else {
471475
return ExtractCoindexedObjectHelper{}(x);
472476
}

flang/lib/Semantics/expression.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2487,6 +2487,15 @@ auto ExpressionAnalyzer::AnalyzeProcedureComponentRef(
24872487
return CalleeAndArguments{
24882488
ProcedureDesignator{*resolution}, std::move(arguments)};
24892489
} else if (dataRef.has_value()) {
2490+
if (ExtractCoarrayRef(*dataRef)) {
2491+
if (IsProcedurePointer(*sym)) {
2492+
Say(sc.component.source,
2493+
"Base of procedure component reference may not be coindexed"_err_en_US);
2494+
} else {
2495+
Say(sc.component.source,
2496+
"A procedure binding may not be coindexed unless it can be resolved at compilation time"_err_en_US);
2497+
}
2498+
}
24902499
if (sym->attrs().test(semantics::Attr::NOPASS)) {
24912500
const auto *dtSpec{GetDerivedTypeSpec(dtExpr->GetType())};
24922501
if (dtSpec && dtSpec->scope()) {

flang/test/Semantics/bindings01.f90

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,48 @@ subroutine t2p
293293
end
294294
end
295295

296+
module m12
297+
type t
298+
procedure(sub), pointer, nopass :: pp
299+
contains
300+
procedure, non_overridable, nopass :: tbp1 => sub
301+
procedure, nopass :: tbp2 => sub
302+
generic :: gen1 => tbp1
303+
generic :: gen2 => tbp2
304+
end type
305+
contains
306+
subroutine sub
307+
end
308+
subroutine test(x, y)
309+
class(t) :: x[*]
310+
type(t) :: y[*]
311+
call x%pp ! ok
312+
call y%pp ! ok
313+
!ERROR: Base of procedure component reference may not be coindexed
314+
call x[1]%pp
315+
!ERROR: Base of procedure component reference may not be coindexed
316+
call y[1]%pp
317+
call x%tbp1 ! ok
318+
call y%tbp1 ! ok
319+
call x[1]%tbp1 ! ok
320+
call y[1]%tbp1 ! ok
321+
call x%tbp2 ! ok
322+
call y%tbp2 ! ok
323+
!ERROR: A procedure binding may not be coindexed unless it can be resolved at compilation time
324+
call x[1]%tbp2
325+
call y[1]%tbp2 ! ok
326+
call x%gen1 ! ok
327+
call y%gen1 ! ok
328+
call x[1]%gen1 ! ok
329+
call y[1]%gen1 ! ok
330+
call x%gen2 ! ok
331+
call y%gen2 ! ok
332+
!ERROR: A procedure binding may not be coindexed unless it can be resolved at compilation time
333+
call x[1]%gen2
334+
call y[1]%gen2 ! ok
335+
end
336+
end
337+
296338
program test
297339
use m1
298340
type,extends(t) :: t2

0 commit comments

Comments
 (0)