aboutsummaryrefslogtreecommitdiff
path: root/flang
diff options
context:
space:
mode:
authorpeter klausler <pklausler@nvidia.com>2021-01-21 14:54:53 -0800
committerpeter klausler <pklausler@nvidia.com>2021-01-21 16:59:51 -0800
commit2de5ea3b3ed9882026d9dc6c5d8ec462ebe5f8ec (patch)
treeca7fc75887157f1e4a60c80c315e5de8764d4fda /flang
parent1be2524b7d213035e591bee3eecccdd6b59d14a5 (diff)
downloadllvm-2de5ea3b3ed9882026d9dc6c5d8ec462ebe5f8ec.zip
llvm-2de5ea3b3ed9882026d9dc6c5d8ec462ebe5f8ec.tar.gz
llvm-2de5ea3b3ed9882026d9dc6c5d8ec462ebe5f8ec.tar.bz2
[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
Diffstat (limited to 'flang')
-rw-r--r--flang/lib/Evaluate/call.cpp9
-rw-r--r--flang/lib/Semantics/check-declarations.cpp40
-rw-r--r--flang/test/Semantics/call17.f9019
-rw-r--r--flang/test/Semantics/resolve88.f902
4 files changed, 48 insertions, 22 deletions
diff --git a/flang/lib/Evaluate/call.cpp b/flang/lib/Evaluate/call.cpp
index 3fe56ab..395751a 100644
--- a/flang/lib/Evaluate/call.cpp
+++ b/flang/lib/Evaluate/call.cpp
@@ -117,9 +117,12 @@ int ProcedureDesignator::Rank() const {
const Symbol *ProcedureDesignator::GetInterfaceSymbol() const {
if (const Symbol * symbol{GetSymbol()}) {
- if (const auto *details{
- symbol->detailsIf<semantics::ProcEntityDetails>()}) {
- return details->interface().symbol();
+ const Symbol &ultimate{symbol->GetUltimate()};
+ if (const auto *proc{ultimate.detailsIf<semantics::ProcEntityDetails>()}) {
+ return proc->interface().symbol();
+ } else if (const auto *binding{
+ ultimate.detailsIf<semantics::ProcBindingDetails>()}) {
+ return &binding->symbol();
}
}
return nullptr;
diff --git a/flang/lib/Semantics/check-declarations.cpp b/flang/lib/Semantics/check-declarations.cpp
index aca5392..cd35047 100644
--- a/flang/lib/Semantics/check-declarations.cpp
+++ b/flang/lib/Semantics/check-declarations.cpp
@@ -53,8 +53,7 @@ private:
evaluate::CheckSpecificationExpr(x, DEREF(scope_), foldingContext_);
}
void CheckValue(const Symbol &, const DerivedTypeSpec *);
- void CheckVolatile(
- const Symbol &, bool isAssociated, const DerivedTypeSpec *);
+ void CheckVolatile(const Symbol &, const DerivedTypeSpec *);
void CheckPointer(const Symbol &);
void CheckPassArg(
const Symbol &proc, const Symbol *interface, const WithPassArg &);
@@ -172,22 +171,18 @@ void CheckHelper::Check(const Symbol &symbol) {
context_.set_location(symbol.name());
const DeclTypeSpec *type{symbol.GetType()};
const DerivedTypeSpec *derived{type ? type->AsDerived() : nullptr};
- bool isAssociated{symbol.has<UseDetails>() || symbol.has<HostAssocDetails>()};
- if (symbol.attrs().test(Attr::VOLATILE)) {
- CheckVolatile(symbol, isAssociated, derived);
- }
- if (isAssociated) {
- if (const auto *details{symbol.detailsIf<HostAssocDetails>()}) {
- CheckHostAssoc(symbol, *details);
- }
- return; // no other checks on associated symbols
- }
- if (IsPointer(symbol)) {
- CheckPointer(symbol);
- }
+ bool isDone{false};
std::visit(
common::visitors{
- [&](const ProcBindingDetails &x) { CheckProcBinding(symbol, x); },
+ [&](const UseDetails &x) { isDone = true; },
+ [&](const HostAssocDetails &x) {
+ CheckHostAssoc(symbol, x);
+ isDone = true;
+ },
+ [&](const ProcBindingDetails &x) {
+ CheckProcBinding(symbol, x);
+ isDone = true;
+ },
[&](const ObjectEntityDetails &x) { CheckObjectEntity(symbol, x); },
[&](const ProcEntityDetails &x) { CheckProcEntity(symbol, x); },
[&](const SubprogramDetails &x) { CheckSubprogram(symbol, x); },
@@ -196,6 +191,15 @@ void CheckHelper::Check(const Symbol &symbol) {
[](const auto &) {},
},
symbol.details());
+ if (symbol.attrs().test(Attr::VOLATILE)) {
+ CheckVolatile(symbol, derived);
+ }
+ if (isDone) {
+ return; // following checks do not apply
+ }
+ if (IsPointer(symbol)) {
+ CheckPointer(symbol);
+ }
if (InPure()) {
if (IsSaved(symbol)) {
messages_.Say(
@@ -1279,7 +1283,7 @@ const Procedure *CheckHelper::Characterize(const Symbol &symbol) {
return common::GetPtrFromOptional(it->second);
}
-void CheckHelper::CheckVolatile(const Symbol &symbol, bool isAssociated,
+void CheckHelper::CheckVolatile(const Symbol &symbol,
const DerivedTypeSpec *derived) { // C866 - C868
if (IsIntentIn(symbol)) {
messages_.Say(
@@ -1288,7 +1292,7 @@ void CheckHelper::CheckVolatile(const Symbol &symbol, bool isAssociated,
if (IsProcedure(symbol)) {
messages_.Say("VOLATILE attribute may apply only to a variable"_err_en_US);
}
- if (isAssociated) {
+ if (symbol.has<UseDetails>() || symbol.has<HostAssocDetails>()) {
const Symbol &ultimate{symbol.GetUltimate()};
if (IsCoarray(ultimate)) {
messages_.Say(
diff --git a/flang/test/Semantics/call17.f90 b/flang/test/Semantics/call17.f90
new file mode 100644
index 0000000..1f4d2c4
--- /dev/null
+++ b/flang/test/Semantics/call17.f90
@@ -0,0 +1,19 @@
+! RUN: %f18 -fparse-only $s 2>&1 | FileCheck %s
+
+! Regression test: don't emit a bogus error about an invalid specification expression
+! in the declaration of a binding
+
+module m
+ type :: t
+ integer :: n
+ contains
+ !CHECK-NOT: Invalid specification expression
+ procedure :: binding => func
+ end type
+ contains
+ function func(x)
+ class(t), intent(in) :: x
+ character(len=x%n) :: func
+ func = ' '
+ end function
+end module
diff --git a/flang/test/Semantics/resolve88.f90 b/flang/test/Semantics/resolve88.f90
index 19217e6..bbbdac2 100644
--- a/flang/test/Semantics/resolve88.f90
+++ b/flang/test/Semantics/resolve88.f90
@@ -11,8 +11,8 @@ module m
real, allocatable, codimension[:] :: allocatableField
!ERROR: Component 'deferredfield' is a coarray and must have the ALLOCATABLE attribute
real, codimension[:] :: deferredField
- !ERROR: 'pointerfield' may not have the POINTER attribute because it is a coarray
!ERROR: Component 'pointerfield' is a coarray and must have the ALLOCATABLE attribute
+ !ERROR: 'pointerfield' may not have the POINTER attribute because it is a coarray
real, pointer, codimension[:] :: pointerField
!ERROR: Component 'realfield' is a coarray and must have the ALLOCATABLE attribute and have a deferred coshape
real, codimension[*] :: realField