[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 08:18:46 PDT 2026


https://github.com/Saieiei updated https://github.com/llvm/llvm-project/pull/192049

>From dc680c4e9d5422a97cf3e8f905854f0d2ce98d6b 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 ++--
 flang-rt/unittests/Runtime/Descriptor.cpp | 28 +++++++++++++++++++++++
 2 files changed, 31 insertions(+), 2 deletions(-)

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/unittests/Runtime/Descriptor.cpp b/flang-rt/unittests/Runtime/Descriptor.cpp
index 7737b91d8a5b4..fc7f266dd17c6 100644
--- a/flang-rt/unittests/Runtime/Descriptor.cpp
+++ b/flang-rt/unittests/Runtime/Descriptor.cpp
@@ -280,3 +280,31 @@ TEST(Descriptor, Dump) {
   fclose(tmpf);
 }
 #endif // defined(__linux__) && !defined(__ANDROID__)
+
+// Verify that Descriptor::BytesFor returns the correct storage size
+// for Real and Complex types, especially for kind=10 where the x87
+// 80-bit extended precision value is stored in a 16-byte container.
+TEST(Descriptor, BytesForRealAndComplex) {
+  using TC = TypeCategory;
+  // Real kinds: storage size should account for container padding
+  EXPECT_EQ(Descriptor::BytesFor(TC::Real, 2), 2u);
+  EXPECT_EQ(Descriptor::BytesFor(TC::Real, 3), 2u);
+  EXPECT_EQ(Descriptor::BytesFor(TC::Real, 4), 4u);
+  EXPECT_EQ(Descriptor::BytesFor(TC::Real, 8), 8u);
+  EXPECT_EQ(Descriptor::BytesFor(TC::Real, 10),
+      16u); // x87: 80-bit in 128-bit container
+  EXPECT_EQ(Descriptor::BytesFor(TC::Real, 16), 16u);
+  // Complex kinds: should be twice the Real storage size
+  EXPECT_EQ(Descriptor::BytesFor(TC::Complex, 2), 4u);
+  EXPECT_EQ(Descriptor::BytesFor(TC::Complex, 3), 4u);
+  EXPECT_EQ(Descriptor::BytesFor(TC::Complex, 4), 8u);
+  EXPECT_EQ(Descriptor::BytesFor(TC::Complex, 8), 16u);
+  EXPECT_EQ(Descriptor::BytesFor(TC::Complex, 10), 32u); // x87: 2 * 16 bytes
+  EXPECT_EQ(Descriptor::BytesFor(TC::Complex, 16), 32u);
+  // Integer and Logical kinds: storage size equals the kind value
+  EXPECT_EQ(Descriptor::BytesFor(TC::Integer, 1), 1u);
+  EXPECT_EQ(Descriptor::BytesFor(TC::Integer, 4), 4u);
+  EXPECT_EQ(Descriptor::BytesFor(TC::Integer, 8), 8u);
+  EXPECT_EQ(Descriptor::BytesFor(TC::Logical, 1), 1u);
+  EXPECT_EQ(Descriptor::BytesFor(TC::Logical, 4), 4u);
+}



More information about the llvm-commits mailing list