[flang-commits] [PATCH] D107918: [flang] Fix crash in runtime-type-info.cpp

Peter Klausler via Phabricator via flang-commits flang-commits at lists.llvm.org
Wed Aug 11 10:28:53 PDT 2021


klausler created this revision.
klausler added a reviewer: jeanPerier.
klausler added a project: Flang.
Herald added subscribers: jdoerfert, kristof.beyls.
klausler requested review of this revision.

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.


https://reviews.llvm.org/D107918

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


Index: flang/test/Semantics/typeinfo01.f90
===================================================================
--- flang/test/Semantics/typeinfo01.f90
+++ flang/test/Semantics/typeinfo01.f90
@@ -253,3 +253,22 @@
     ! 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
Index: flang/lib/Semantics/runtime-type-info.cpp
===================================================================
--- flang/lib/Semantics/runtime-type-info.cpp
+++ flang/lib/Semantics/runtime-type-info.cpp
@@ -955,9 +955,27 @@
     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() &&
Index: flang/include/flang/Semantics/type.h
===================================================================
--- flang/include/flang/Semantics/type.h
+++ flang/include/flang/Semantics/type.h
@@ -288,6 +288,9 @@
   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:


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D107918.365793.patch
Type: text/x-patch
Size: 3089 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/flang-commits/attachments/20210811/299a23af/attachment-0001.bin>


More information about the flang-commits mailing list