[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