[flang-commits] [flang] 467525b - [flang] Fix crash in runtime-type-info.cpp

peter klausler via flang-commits flang-commits at lists.llvm.org
Thu Aug 12 09:32:14 PDT 2021


Author: peter klausler
Date: 2021-08-12T09:32:08-07:00
New Revision: 467525bd07942a1f9be97bbcc3cc4ed83ed5d9c1

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

LOG: [flang] Fix crash in runtime-type-info.cpp

Recent work in runtime assignments failed an assertion in fir-dev
while running tests (flang/test/Semantics/defined-ops.f90).  This
test didn't fail in llvm-project/main because only the "new" Arm
driver is used now, and that only builds runtime derived type information
tables when some debug dumping options are enabled.

So add a reproducing test case to another test that is run with
-fdebug-dump-symbols, and fix the crash by emitting special procedure
binding information only for type-bound generic ASSIGNMENT(=) bindings
that are relevant to the runtime support library for use in intrinsic
assignment of derived types.

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

Added: 
    

Modified: 
    flang/include/flang/Semantics/type.h
    flang/lib/Semantics/runtime-type-info.cpp
    flang/test/Semantics/typeinfo01.f90

Removed: 
    


################################################################################
diff  --git a/flang/include/flang/Semantics/type.h b/flang/include/flang/Semantics/type.h
index 1ddfe0160a51..09ba75fcd956 100644
--- a/flang/include/flang/Semantics/type.h
+++ b/flang/include/flang/Semantics/type.h
@@ -288,6 +288,9 @@ class DerivedTypeSpec {
   bool operator==(const DerivedTypeSpec &that) const {
     return RawEquals(that) && parameters_ == that.parameters_;
   }
+  bool operator!=(const DerivedTypeSpec &that) const {
+    return !(*this == that);
+  }
   std::string AsFortran() const;
 
 private:

diff  --git a/flang/lib/Semantics/runtime-type-info.cpp b/flang/lib/Semantics/runtime-type-info.cpp
index f8c74460e742..045ced4514ea 100644
--- a/flang/lib/Semantics/runtime-type-info.cpp
+++ b/flang/lib/Semantics/runtime-type-info.cpp
@@ -955,9 +955,27 @@ void RuntimeTableBuilder::DescribeSpecialProc(
     std::uint8_t isArgDescriptorSet{0};
     int argThatMightBeDescriptor{0};
     MaybeExpr which;
-    if (isAssignment) { // only type-bound asst's are germane to runtime
-      CHECK(binding != nullptr);
+    if (isAssignment) {
+      // Only type-bound asst's with the same type on both dummy arguments
+      // are germane to the runtime, which needs only these to implement
+      // component assignment as part of intrinsic assignment.
+      // Non-type-bound generic INTERFACEs and assignments from distinct
+      // types must not be used for component intrinsic assignment.
       CHECK(proc->dummyArguments.size() == 2);
+      const auto t1{
+          DEREF(std::get_if<evaluate::characteristics::DummyDataObject>(
+                    &proc->dummyArguments[0].u))
+              .type.type()};
+      const auto t2{
+          DEREF(std::get_if<evaluate::characteristics::DummyDataObject>(
+                    &proc->dummyArguments[1].u))
+              .type.type()};
+      if (!binding || t1.category() != TypeCategory::Derived ||
+          t2.category() != TypeCategory::Derived ||
+          t1.IsUnlimitedPolymorphic() || t2.IsUnlimitedPolymorphic() ||
+          t1.GetDerivedTypeSpec() != t2.GetDerivedTypeSpec()) {
+        return;
+      }
       which = proc->IsElemental() ? elementalAssignmentEnum_
                                   : scalarAssignmentEnum_;
       if (binding && binding->passName() &&

diff  --git a/flang/test/Semantics/typeinfo01.f90 b/flang/test/Semantics/typeinfo01.f90
index e760f535ea73..52dd5d5d77b5 100644
--- a/flang/test/Semantics/typeinfo01.f90
+++ b/flang/test/Semantics/typeinfo01.f90
@@ -253,3 +253,22 @@ module m12
     ! CHECK: .n.n_3, SAVE, TARGET: ObjectEntity type: CHARACTER(3_8,1) init:"n_3"
   end type
 end module
+
+module m13
+  type :: t1
+    integer :: n
+   contains
+    procedure :: assign1, assign2
+    generic :: assignment(=) => assign1, assign2
+    ! CHECK: .s.t1, SAVE, TARGET: ObjectEntity type: TYPE(specialbinding) shape: 0_8:0_8 init:[specialbinding::specialbinding(which=2_1,isargdescriptorset=3_1,proc=assign1)]
+  end type
+ contains
+  impure elemental subroutine assign1(to, from)
+    class(t1), intent(out) :: to
+    class(t1), intent(in) :: from
+  end subroutine
+  impure elemental subroutine assign2(to, from)
+    class(t1), intent(out) :: to
+    integer, intent(in) :: from
+  end subroutine
+end module


        


More information about the flang-commits mailing list