[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