Skip to content

Commit e2eabb7

Browse files
committed
[flang] Ignore errors on declarations in interfaces that "have no effect"
Fortran strangely allows declarations to appear in procedure interface definitions when those declarations do not contribute anything to the characteristics of the procedure; in particular, one may declare local variables that are neither dummy variables nor function results. Such declarations "have no effect" on the semantics of the program, and that should include semantic error checking for things like special restrictions on PURE procedures. Differential Revision: https://reviews.llvm.org/D135209
1 parent 4ea1a64 commit e2eabb7

File tree

2 files changed

+54
-21
lines changed

2 files changed

+54
-21
lines changed

flang/lib/Semantics/check-declarations.cpp

Lines changed: 35 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,12 @@ class CheckHelper {
9696
bool InFunction() const {
9797
return innermostSymbol_ && IsFunction(*innermostSymbol_);
9898
}
99+
bool InInterface() const {
100+
const SubprogramDetails *subp{innermostSymbol_
101+
? innermostSymbol_->detailsIf<SubprogramDetails>()
102+
: nullptr};
103+
return subp && subp->isInterface();
104+
}
99105
template <typename... A>
100106
void SayWithDeclaration(const Symbol &symbol, A &&...x) {
101107
if (parser::Message * msg{messages_.Say(std::forward<A>(x)...)}) {
@@ -247,36 +253,44 @@ void CheckHelper::Check(const Symbol &symbol) {
247253
CheckPointer(symbol);
248254
}
249255
if (InPure()) {
250-
if (IsSaved(symbol)) {
251-
if (IsInitialized(symbol)) {
252-
messages_.Say(
253-
"A pure subprogram may not initialize a variable"_err_en_US);
254-
} else {
255-
messages_.Say(
256-
"A pure subprogram may not have a variable with the SAVE attribute"_err_en_US);
256+
if (InInterface()) {
257+
// Declarations in interface definitions "have no effect" if they
258+
// are not pertinent to the characteristics of the procedure.
259+
// Restrictions on entities in pure procedure interfaces don't need
260+
// enforcement.
261+
} else {
262+
if (IsSaved(symbol)) {
263+
if (IsInitialized(symbol)) {
264+
messages_.Say(
265+
"A pure subprogram may not initialize a variable"_err_en_US);
266+
} else {
267+
messages_.Say(
268+
"A pure subprogram may not have a variable with the SAVE attribute"_err_en_US);
269+
}
270+
}
271+
if (!IsDummy(symbol) && !IsFunctionResult(symbol)) {
272+
if (IsPolymorphicAllocatable(symbol)) {
273+
SayWithDeclaration(symbol,
274+
"Deallocation of polymorphic object '%s' is not permitted in a pure subprogram"_err_en_US,
275+
symbol.name());
276+
} else if (derived) {
277+
if (auto bad{FindPolymorphicAllocatableUltimateComponent(*derived)}) {
278+
SayWithDeclaration(*bad,
279+
"Deallocation of polymorphic object '%s%s' is not permitted in a pure subprogram"_err_en_US,
280+
symbol.name(), bad.BuildResultDesignatorName());
281+
}
282+
}
257283
}
258284
}
259-
if (symbol.attrs().test(Attr::VOLATILE)) {
285+
if (symbol.attrs().test(Attr::VOLATILE) &&
286+
(IsDummy(symbol) || !InInterface())) {
260287
messages_.Say(
261288
"A pure subprogram may not have a variable with the VOLATILE attribute"_err_en_US);
262289
}
263290
if (IsProcedure(symbol) && !IsPureProcedure(symbol) && IsDummy(symbol)) {
264291
messages_.Say(
265292
"A dummy procedure of a pure subprogram must be pure"_err_en_US);
266293
}
267-
if (!IsDummy(symbol) && !IsFunctionResult(symbol)) {
268-
if (IsPolymorphicAllocatable(symbol)) {
269-
SayWithDeclaration(symbol,
270-
"Deallocation of polymorphic object '%s' is not permitted in a pure subprogram"_err_en_US,
271-
symbol.name());
272-
} else if (derived) {
273-
if (auto bad{FindPolymorphicAllocatableUltimateComponent(*derived)}) {
274-
SayWithDeclaration(*bad,
275-
"Deallocation of polymorphic object '%s%s' is not permitted in a pure subprogram"_err_en_US,
276-
symbol.name(), bad.BuildResultDesignatorName());
277-
}
278-
}
279-
}
280294
}
281295
if (type) { // Section 7.2, paragraph 7
282296
bool canHaveAssumedParameter{IsNamedConstant(symbol) ||

flang/test/Semantics/call10.f90

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,25 @@ module m
1717

1818
real, volatile, target :: volatile
1919

20+
interface
21+
! Ensure no errors for "ignored" declarations in a pure interface.
22+
! These declarations do not contribute to the characteristics of
23+
! the procedure and must not elicit spurious errors about being used
24+
! in a pure procedure.
25+
pure subroutine s05a
26+
import polyAlloc
27+
real, save :: v1
28+
real :: v2 = 0.
29+
real :: v3
30+
data v3/0./
31+
real :: v4
32+
common /blk/ v4
33+
save /blk/
34+
type(polyAlloc) :: v5
35+
real, volatile :: v6
36+
end subroutine
37+
end interface
38+
2039
contains
2140

2241
subroutine impure(x)

0 commit comments

Comments
 (0)