[llvm] [flang] Fix REAL(10)/COMPLEX(10) component sizes in runtime type info (PR #192049)
Sairudra More via llvm-commits
llvm-commits at lists.llvm.org
Tue Apr 14 06:01:14 PDT 2026
https://github.com/Saieiei updated https://github.com/llvm/llvm-project/pull/192049
>From d9501ce149aca5010f8b34626a4ca9b84658b707 Mon Sep 17 00:00:00 2001
From: Sairudra More <moresair at pe31.hpc.amslabs.hpecorp.net>
Date: Tue, 14 Apr 2026 07:46:11 -0500
Subject: [PATCH] [flang] Fix REAL(10)/COMPLEX(10) component sizes in runtime
type info
For REAL(10) and COMPLEX(10) components, Component::GetElementByteSize()
was using the Fortran kind value as the byte size. On x86-64 that
underestimates the actual storage size (10 vs 16 bytes for REAL(10),
20 vs 32 for COMPLEX(10)), so strided componentwise assignment of
SEQUENCE types can corrupt adjacent data and crash.
Route REAL and COMPLEX component sizes through Descriptor::BytesFor(),
which matches the runtime existing storage-size handling.
Add a regression test covering strided assignment of a SEQUENCE type
with REAL(10)/COMPLEX(10) components.
---
flang-rt/lib/runtime/type-info.cpp | 5 +-
.../Driver/derived-type-real10-assign.f90 | 60 +++++++++++++++++++
2 files changed, 63 insertions(+), 2 deletions(-)
create mode 100644 flang-rt/test/Driver/derived-type-real10-assign.f90
diff --git a/flang-rt/lib/runtime/type-info.cpp b/flang-rt/lib/runtime/type-info.cpp
index cb8e894bd3922..c5acfad3a98e3 100644
--- a/flang-rt/lib/runtime/type-info.cpp
+++ b/flang-rt/lib/runtime/type-info.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "flang-rt/runtime/type-info.h"
+#include "flang-rt/runtime/descriptor.h"
#include "flang-rt/runtime/terminator.h"
#include "flang-rt/runtime/tools.h"
#include <cstdio>
@@ -37,11 +38,11 @@ RT_API_ATTRS std::size_t Component::GetElementByteSize(
switch (category()) {
case TypeCategory::Integer:
case TypeCategory::Unsigned:
- case TypeCategory::Real:
case TypeCategory::Logical:
return kind_;
+ case TypeCategory::Real:
case TypeCategory::Complex:
- return 2 * kind_;
+ return Descriptor::BytesFor(category(), kind_);
case TypeCategory::Character:
if (auto value{characterLen_.GetValue(&instance)}) {
return kind_ * *value;
diff --git a/flang-rt/test/Driver/derived-type-real10-assign.f90 b/flang-rt/test/Driver/derived-type-real10-assign.f90
new file mode 100644
index 0000000000000..d71ea8568f3b0
--- /dev/null
+++ b/flang-rt/test/Driver/derived-type-real10-assign.f90
@@ -0,0 +1,60 @@
+! Test that componentwise assignment of SEQUENCE types with REAL(10) and
+! COMPLEX(10) components copies the correct number of bytes. On x86-64,
+! REAL(10) occupies 16 bytes (not 10) and COMPLEX(10) occupies 32 bytes
+! (not 20). A bug in Component::GetElementByteSize() previously returned
+! the Fortran kind value instead of the actual storage size, corrupting
+! subsequent fields during strided derived-type assignment.
+
+! UNSUPPORTED: system-windows
+! UNSUPPORTED: offload-cuda
+
+! RUN: %flang -L"%libdir" %s -o %t
+! RUN: env LD_LIBRARY_PATH="$LD_LIBRARY_PATH:%libdir" %t | FileCheck %s
+
+! CHECK: PASS
+
+program derived_type_real10_assign
+ implicit none
+
+ type :: seq_t
+ sequence
+ real(10) :: r
+ complex(10) :: z
+ integer :: tag
+ end type
+
+ type(seq_t) :: a(4), b(4)
+ integer :: i
+
+ ! Initialize source array
+ do i = 1, 4
+ a(i)%r = real(i * 100, 10)
+ a(i)%z = cmplx(real(i, 10), real(i * 10, 10))
+ a(i)%tag = i
+ end do
+
+ ! Initialize destination with different values
+ do i = 1, 4
+ b(i)%r = 0.0_10
+ b(i)%z = (0.0_10, 0.0_10)
+ b(i)%tag = 0
+ end do
+
+ ! Strided section assignment — forces componentwise copy in the runtime
+ b(1:3:2) = a(2:4:2)
+
+ ! b(1) should equal a(2), b(3) should equal a(4)
+ ! b(2) and b(4) should remain zero
+ if (b(1)%r /= a(2)%r) stop 1
+ if (b(1)%z /= a(2)%z) stop 2
+ if (b(1)%tag /= a(2)%tag) stop 3
+ if (b(3)%r /= a(4)%r) stop 4
+ if (b(3)%z /= a(4)%z) stop 5
+ if (b(3)%tag /= a(4)%tag) stop 6
+
+ ! Verify untouched elements
+ if (b(2)%tag /= 0) stop 7
+ if (b(4)%tag /= 0) stop 8
+
+ print *, 'PASS'
+end program
More information about the llvm-commits
mailing list