[llvm-branch-commits] [flang] 2de5ea3 - [flang] Fix bogus error message with binding

peter klausler via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Thu Jan 21 17:04:35 PST 2021


Author: peter klausler
Date: 2021-01-21T16:59:51-08:00
New Revision: 2de5ea3b3ed9882026d9dc6c5d8ec462ebe5f8ec

URL: https://github.com/llvm/llvm-project/commit/2de5ea3b3ed9882026d9dc6c5d8ec462ebe5f8ec
DIFF: https://github.com/llvm/llvm-project/commit/2de5ea3b3ed9882026d9dc6c5d8ec462ebe5f8ec.diff

LOG: [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

Added: 
    flang/test/Semantics/call17.f90

Modified: 
    flang/lib/Evaluate/call.cpp
    flang/lib/Semantics/check-declarations.cpp
    flang/test/Semantics/resolve88.f90

Removed: 
    


################################################################################
diff  --git a/flang/lib/Evaluate/call.cpp b/flang/lib/Evaluate/call.cpp
index 3fe56ab4874b..395751acabda 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 aca5392e507f..cd35047681e3 100644
--- a/flang/lib/Semantics/check-declarations.cpp
+++ b/flang/lib/Semantics/check-declarations.cpp
@@ -53,8 +53,7 @@ class CheckHelper {
     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 000000000000..1f4d2c4d9186
--- /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 19217e69be27..bbbdac2654b3 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


        


More information about the llvm-branch-commits mailing list