Skip to content

Commit 2de5ea3

Browse files
committed
[flang] Fix bogus error message with binding
ProcedureDesignator::GetInterfaceSymbol() needs to return the procedure bound to a bindings. Differential Revision: https://reviews.llvm.org/D95178
1 parent 1be2524 commit 2de5ea3

File tree

4 files changed

+48
-22
lines changed

4 files changed

+48
-22
lines changed

flang/lib/Evaluate/call.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -117,9 +117,12 @@ int ProcedureDesignator::Rank() const {
117117

118118
const Symbol *ProcedureDesignator::GetInterfaceSymbol() const {
119119
if (const Symbol * symbol{GetSymbol()}) {
120-
if (const auto *details{
121-
symbol->detailsIf<semantics::ProcEntityDetails>()}) {
122-
return details->interface().symbol();
120+
const Symbol &ultimate{symbol->GetUltimate()};
121+
if (const auto *proc{ultimate.detailsIf<semantics::ProcEntityDetails>()}) {
122+
return proc->interface().symbol();
123+
} else if (const auto *binding{
124+
ultimate.detailsIf<semantics::ProcBindingDetails>()}) {
125+
return &binding->symbol();
123126
}
124127
}
125128
return nullptr;

flang/lib/Semantics/check-declarations.cpp

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,7 @@ class CheckHelper {
5353
evaluate::CheckSpecificationExpr(x, DEREF(scope_), foldingContext_);
5454
}
5555
void CheckValue(const Symbol &, const DerivedTypeSpec *);
56-
void CheckVolatile(
57-
const Symbol &, bool isAssociated, const DerivedTypeSpec *);
56+
void CheckVolatile(const Symbol &, const DerivedTypeSpec *);
5857
void CheckPointer(const Symbol &);
5958
void CheckPassArg(
6059
const Symbol &proc, const Symbol *interface, const WithPassArg &);
@@ -172,22 +171,18 @@ void CheckHelper::Check(const Symbol &symbol) {
172171
context_.set_location(symbol.name());
173172
const DeclTypeSpec *type{symbol.GetType()};
174173
const DerivedTypeSpec *derived{type ? type->AsDerived() : nullptr};
175-
bool isAssociated{symbol.has<UseDetails>() || symbol.has<HostAssocDetails>()};
176-
if (symbol.attrs().test(Attr::VOLATILE)) {
177-
CheckVolatile(symbol, isAssociated, derived);
178-
}
179-
if (isAssociated) {
180-
if (const auto *details{symbol.detailsIf<HostAssocDetails>()}) {
181-
CheckHostAssoc(symbol, *details);
182-
}
183-
return; // no other checks on associated symbols
184-
}
185-
if (IsPointer(symbol)) {
186-
CheckPointer(symbol);
187-
}
174+
bool isDone{false};
188175
std::visit(
189176
common::visitors{
190-
[&](const ProcBindingDetails &x) { CheckProcBinding(symbol, x); },
177+
[&](const UseDetails &x) { isDone = true; },
178+
[&](const HostAssocDetails &x) {
179+
CheckHostAssoc(symbol, x);
180+
isDone = true;
181+
},
182+
[&](const ProcBindingDetails &x) {
183+
CheckProcBinding(symbol, x);
184+
isDone = true;
185+
},
191186
[&](const ObjectEntityDetails &x) { CheckObjectEntity(symbol, x); },
192187
[&](const ProcEntityDetails &x) { CheckProcEntity(symbol, x); },
193188
[&](const SubprogramDetails &x) { CheckSubprogram(symbol, x); },
@@ -196,6 +191,15 @@ void CheckHelper::Check(const Symbol &symbol) {
196191
[](const auto &) {},
197192
},
198193
symbol.details());
194+
if (symbol.attrs().test(Attr::VOLATILE)) {
195+
CheckVolatile(symbol, derived);
196+
}
197+
if (isDone) {
198+
return; // following checks do not apply
199+
}
200+
if (IsPointer(symbol)) {
201+
CheckPointer(symbol);
202+
}
199203
if (InPure()) {
200204
if (IsSaved(symbol)) {
201205
messages_.Say(
@@ -1279,7 +1283,7 @@ const Procedure *CheckHelper::Characterize(const Symbol &symbol) {
12791283
return common::GetPtrFromOptional(it->second);
12801284
}
12811285

1282-
void CheckHelper::CheckVolatile(const Symbol &symbol, bool isAssociated,
1286+
void CheckHelper::CheckVolatile(const Symbol &symbol,
12831287
const DerivedTypeSpec *derived) { // C866 - C868
12841288
if (IsIntentIn(symbol)) {
12851289
messages_.Say(
@@ -1288,7 +1292,7 @@ void CheckHelper::CheckVolatile(const Symbol &symbol, bool isAssociated,
12881292
if (IsProcedure(symbol)) {
12891293
messages_.Say("VOLATILE attribute may apply only to a variable"_err_en_US);
12901294
}
1291-
if (isAssociated) {
1295+
if (symbol.has<UseDetails>() || symbol.has<HostAssocDetails>()) {
12921296
const Symbol &ultimate{symbol.GetUltimate()};
12931297
if (IsCoarray(ultimate)) {
12941298
messages_.Say(

flang/test/Semantics/call17.f90

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
! RUN: %f18 -fparse-only $s 2>&1 | FileCheck %s
2+
3+
! Regression test: don't emit a bogus error about an invalid specification expression
4+
! in the declaration of a binding
5+
6+
module m
7+
type :: t
8+
integer :: n
9+
contains
10+
!CHECK-NOT: Invalid specification expression
11+
procedure :: binding => func
12+
end type
13+
contains
14+
function func(x)
15+
class(t), intent(in) :: x
16+
character(len=x%n) :: func
17+
func = ' '
18+
end function
19+
end module

flang/test/Semantics/resolve88.f90

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ module m
1111
real, allocatable, codimension[:] :: allocatableField
1212
!ERROR: Component 'deferredfield' is a coarray and must have the ALLOCATABLE attribute
1313
real, codimension[:] :: deferredField
14-
!ERROR: 'pointerfield' may not have the POINTER attribute because it is a coarray
1514
!ERROR: Component 'pointerfield' is a coarray and must have the ALLOCATABLE attribute
15+
!ERROR: 'pointerfield' may not have the POINTER attribute because it is a coarray
1616
real, pointer, codimension[:] :: pointerField
1717
!ERROR: Component 'realfield' is a coarray and must have the ALLOCATABLE attribute and have a deferred coshape
1818
real, codimension[*] :: realField

0 commit comments

Comments
 (0)