[flang-commits] [flang] a3c6a7d - [flang] Stricter interface compatibility checking for TBP overrides

Peter Klausler via flang-commits flang-commits at lists.llvm.org
Thu Mar 2 10:33:38 PST 2023


Author: Peter Klausler
Date: 2023-03-02T10:20:33-08:00
New Revision: a3c6a7d53d21e09a45171c47456a33d89bc47738

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

LOG: [flang] Stricter interface compatibility checking for TBP overrides

The compiler currently ignores attributes for PASS dummy arguments that
are incompatible between a type-bound procedure in an extended type and
the binding of the same name that it overrides in an ancestor type,
if any.  Strengthen this checking so that discrepancies between attributes
and intents are caught, and add some tests.

Differential Revision: https://reviews.llvm.org/D145110

Added: 
    flang/test/Semantics/bindings04.f90

Modified: 
    flang/lib/Evaluate/characteristics.cpp
    flang/lib/Semantics/check-declarations.cpp

Removed: 
    


################################################################################
diff  --git a/flang/lib/Evaluate/characteristics.cpp b/flang/lib/Evaluate/characteristics.cpp
index 8c9002f3ca1d..bed45fa0e570 100644
--- a/flang/lib/Evaluate/characteristics.cpp
+++ b/flang/lib/Evaluate/characteristics.cpp
@@ -1089,8 +1089,11 @@ bool Procedure::CanOverride(
     return false;
   }
   for (int j{0}; j < argCount; ++j) {
-    if ((!passIndex || j != *passIndex) &&
-        dummyArguments[j] != that.dummyArguments[j]) {
+    if (passIndex && j == *passIndex) {
+      if (!that.dummyArguments[j].IsCompatibleWith(dummyArguments[j])) {
+        return false;
+      }
+    } else if (dummyArguments[j] != that.dummyArguments[j]) {
       return false;
     }
   }

diff  --git a/flang/lib/Semantics/check-declarations.cpp b/flang/lib/Semantics/check-declarations.cpp
index bfb90e2f8fa3..fc93022af209 100644
--- a/flang/lib/Semantics/check-declarations.cpp
+++ b/flang/lib/Semantics/check-declarations.cpp
@@ -1918,7 +1918,7 @@ void CheckHelper::CheckProcBinding(
           if (isNopass) {
             if (!bindingChars->CanOverride(*overriddenChars, std::nullopt)) {
               SayWithDeclaration(*overridden,
-                  "A type-bound procedure and its override must have compatible interfaces"_err_en_US);
+                  "A NOPASS type-bound procedure and its override must have identical interfaces"_err_en_US);
             }
           } else if (!context_.HasError(binding.symbol())) {
             int passIndex{bindingChars->FindPassIndex(binding.passName())};
@@ -1930,7 +1930,7 @@ void CheckHelper::CheckProcBinding(
             } else if (!bindingChars->CanOverride(
                            *overriddenChars, passIndex)) {
               SayWithDeclaration(*overridden,
-                  "A type-bound procedure and its override must have compatible interfaces apart from their passed argument"_err_en_US);
+                  "A type-bound procedure and its override must have compatible interfaces"_err_en_US);
             }
           }
         }

diff  --git a/flang/test/Semantics/bindings04.f90 b/flang/test/Semantics/bindings04.f90
new file mode 100644
index 000000000000..02902719a290
--- /dev/null
+++ b/flang/test/Semantics/bindings04.f90
@@ -0,0 +1,57 @@
+! RUN: %python %S/test_errors.py %s %flang_fc1
+module m1
+  type t1
+   contains
+    procedure :: tbp => s1
+  end type
+  type, extends(t1) :: t1e
+   contains
+    !ERROR: A type-bound procedure and its override must have compatible interfaces
+    procedure :: tbp => s1e
+  end type
+ contains
+  subroutine s1(x)
+    class(t1) :: x
+  end
+  subroutine s1e(x)
+    class(t1e), intent(in out) :: x
+  end
+end
+
+module m2
+  type t1
+   contains
+    procedure :: tbp => s1
+  end type
+  type, extends(t1) :: t1e
+   contains
+    !ERROR: A type-bound procedure and its override must have compatible interfaces
+    procedure :: tbp => s1e
+  end type
+ contains
+  subroutine s1(x)
+    class(t1), intent(in out) :: x
+  end
+  subroutine s1e(x)
+    class(t1e) :: x
+  end
+end
+
+module m3
+  type t1
+   contains
+    procedure, nopass :: tbp => s1
+  end type
+  type, extends(t1) :: t1e
+   contains
+   !ERROR: A NOPASS type-bound procedure and its override must have identical interfaces
+    procedure, nopass :: tbp => s1e
+  end type
+ contains
+  subroutine s1(x)
+    real, intent(in out) :: x
+  end
+  subroutine s1e(x)
+    real :: x
+  end
+end


        


More information about the flang-commits mailing list