[flang-commits] [flang] [llvm] [flang][flang-rt] Treat REAL(2)/COMPLEX(2) as C-interoperable types (PR #201888)

Eugene Epshteyn via flang-commits flang-commits at lists.llvm.org
Fri Jun 5 09:49:34 PDT 2026


https://github.com/eugeneepshteyn updated https://github.com/llvm/llvm-project/pull/201888

>From d0042d700fdbbb4544b027f570fbefb97795973f Mon Sep 17 00:00:00 2001
From: Eugene Epshteyn <eepshteyn at nvidia.com>
Date: Fri, 5 Jun 2026 12:41:28 -0400
Subject: [PATCH 1/2] [flang][flang-rt] Treat REAL(2)/COMPLEX(2) as
 C-interoperable types

IEEE-754 binary16 ("half") maps cleanly to the C `_Float16` type
(ISO/IEC TS 18661-3), but flang previously rejected `REAL(KIND=2)` and
`COMPLEX(KIND=2)` in C-interoperable contexts. Make `REAL(KIND=2)` and
`COMPLEX(KIND=2)` into actual interoperable types.

`ISO_C_BINDING` now exports the gfortran-compatible named constants
`c_float16` and `c_float16_complex` (both value 2), the kind parameter
for the half-precision C interoperable types.

Assisted-by: AI
---
 flang-rt/lib/runtime/iso_c_binding.f90 |  3 +++
 flang/docs/Extensions.md               |  6 +++++
 flang/lib/Evaluate/type.cpp            |  5 ++++-
 flang/test/Semantics/bind-c-real2.f90  | 31 ++++++++++++++++++++++++++
 flang/test/Semantics/bind-c06.f90      |  8 ++++---
 5 files changed, 49 insertions(+), 4 deletions(-)
 create mode 100644 flang/test/Semantics/bind-c-real2.f90

diff --git a/flang-rt/lib/runtime/iso_c_binding.f90 b/flang-rt/lib/runtime/iso_c_binding.f90
index a71839b5fdced..619b1f2e5c6dd 100644
--- a/flang-rt/lib/runtime/iso_c_binding.f90
+++ b/flang-rt/lib/runtime/iso_c_binding.f90
@@ -112,6 +112,9 @@ module iso_c_binding
   public :: c_f_procpointer
 
   ! gfortran extensions
+  integer, parameter, public :: &
+    c_float16 = 2, &
+    c_float16_complex = c_float16
   integer, parameter, public :: &
     c_float128 = 16, &
     c_float128_complex = c_float128
diff --git a/flang/docs/Extensions.md b/flang/docs/Extensions.md
index 2160cdeba598a..f86073db20224 100644
--- a/flang/docs/Extensions.md
+++ b/flang/docs/Extensions.md
@@ -228,6 +228,12 @@ end
   `c_float128_complex` (both with the value 16), the kind parameter for
   128-bit (quad precision) real and complex C interoperable types. These
   extensions are gfortran-compatible.
+* The `ISO_C_BINDING` module exports the named constants `c_float16` and
+  `c_float16_complex` (both with the value 2), the kind parameter for
+  16-bit (half precision) real and complex C interoperable types,
+  corresponding to C `_Float16` (ISO/IEC TS 18661-3). `REAL(KIND=2)` and
+  `COMPLEX(KIND=2)` are accordingly accepted as interoperable types. These
+  extensions are gfortran-compatible.
 * `X` prefix/suffix as synonym for `Z` on hexadecimal literals
 * `B`, `O`, `Z`, and `X` accepted as suffixes as well as prefixes
 * Support for using bare `L` in FORMAT statement
diff --git a/flang/lib/Evaluate/type.cpp b/flang/lib/Evaluate/type.cpp
index 988be5673ad05..5de8bd23c5778 100644
--- a/flang/lib/Evaluate/type.cpp
+++ b/flang/lib/Evaluate/type.cpp
@@ -878,7 +878,10 @@ std::optional<bool> IsInteroperableIntrinsicType(const DynamicType &type,
     return true;
   case TypeCategory::Real:
   case TypeCategory::Complex:
-    return type.kind() >= 4 /* not a short or half float */ || !features ||
+    // KIND=2 is IEEE-754 binary16, interoperable with C _Float16.
+    // KIND=3 (bfloat16) has no standard interoperable C type, so it is
+    // accepted only under CUDA (or when reading a module file).
+    return type.kind() == 2 || type.kind() >= 4 || !features ||
         features->IsEnabled(common::LanguageFeature::CUDA);
   case TypeCategory::Logical:
     return type.kind() == 1; // C_BOOL
diff --git a/flang/test/Semantics/bind-c-real2.f90 b/flang/test/Semantics/bind-c-real2.f90
new file mode 100644
index 0000000000000..7b4c0702953f7
--- /dev/null
+++ b/flang/test/Semantics/bind-c-real2.f90
@@ -0,0 +1,31 @@
+! RUN: %python %S/test_errors.py %s %flang_fc1 -pedantic
+! REAL(KIND=2)/COMPLEX(KIND=2) (IEEE binary16) are interoperable with C
+! _Float16, and ISO_C_BINDING exports c_float16/c_float16_complex (value 2).
+! Verify no diagnostic (including no portability warning under -pedantic),
+! while bfloat16 (KIND=3) stays non-interoperable.
+module m
+  use iso_c_binding, only: c_float16, c_float16_complex
+  integer, parameter :: check = c_float16
+  real(kind=2), bind(c) :: a
+  complex(kind=2), bind(c) :: b
+  real(c_float16), bind(c) :: c
+  complex(c_float16_complex), bind(c) :: d
+
+  type, bind(c) :: t1
+    real(kind=2) :: x
+    complex(kind=2) :: y
+  end type
+
+  type, bind(c) :: t2
+    !ERROR: Each component of an interoperable derived type must have an interoperable type
+    real(kind=3) :: x ! bfloat16 is not interoperable
+  end type
+
+  interface
+    subroutine s(x, y) bind(c)
+      import :: c_float16, c_float16_complex
+      real(c_float16), value :: x
+      complex(c_float16_complex), value :: y
+    end subroutine
+  end interface
+end
diff --git a/flang/test/Semantics/bind-c06.f90 b/flang/test/Semantics/bind-c06.f90
index 608d193ee04de..deb9da8b1ffe7 100644
--- a/flang/test/Semantics/bind-c06.f90
+++ b/flang/test/Semantics/bind-c06.f90
@@ -83,12 +83,14 @@ program main
     logical(kind=8) x
   end type
   type, bind(c) :: t13
-    !ERROR: Each component of an interoperable derived type must have an interoperable type
-    real(kind=2) x
+    real(kind=2) x ! ok, interoperable with C _Float16
   end type
   type, bind(c) :: t14
+    complex(kind=2) x ! ok, interoperable with C _Float16 _Complex
+  end type
+  type, bind(c) :: t13b
     !ERROR: Each component of an interoperable derived type must have an interoperable type
-    complex(kind=2) x
+    real(kind=3) x ! bfloat16 is not interoperable
   end type
   type, bind(c) :: t15
     !ERROR: An array component of an interoperable type must have at least one element

>From 1bb08d9c5d7698e804f3ad96e5580cfefdd69496 Mon Sep 17 00:00:00 2001
From: Eugene Epshteyn <eepshteyn at nvidia.com>
Date: Fri, 5 Jun 2026 12:49:04 -0400
Subject: [PATCH 2/2] Fixed the test type

---
 flang/test/Semantics/bind-c06.f90 | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/flang/test/Semantics/bind-c06.f90 b/flang/test/Semantics/bind-c06.f90
index deb9da8b1ffe7..af48566c7b3fd 100644
--- a/flang/test/Semantics/bind-c06.f90
+++ b/flang/test/Semantics/bind-c06.f90
@@ -90,7 +90,7 @@ program main
   end type
   type, bind(c) :: t13b
     !ERROR: Each component of an interoperable derived type must have an interoperable type
-    real(kind=3) x ! bfloat16 is not interoperable
+    complex(kind=3) x ! bfloat16 is not interoperable
   end type
   type, bind(c) :: t15
     !ERROR: An array component of an interoperable type must have at least one element



More information about the flang-commits mailing list