[clang] [clang] Introduce '-fint64-is-long-long' (PR #234780)

Nathan Chancellor via cfe-commits cfe-commits at lists.llvm.org
Sat Oct 24 09:04:44 PDT 2026


https://github.com/nathanchance updated https://github.com/llvm/llvm-project/pull/234780

>From 3eefd136d0f50c2a3bdb5609696889e418eb9188 Mon Sep 17 00:00:00 2001
From: Nathan Chancellor <nathan at kernel.org>
Date: Thu, 22 Oct 2026 15:09:37 -0700
Subject: [PATCH 1/4] [clang] Introduce '-fint64-is-long-long'

The Linux kernel declares int64_t as 'long long' for all architectures
internally. This can cause issues when including compiler headers such
as arm_neon.h in the build because __{,U}INT64_TYPE__ are redefined to
match the kernel's internal types before the internal version of
stdint.h for freestanding environments is included but the compiler has
no knowledge of this redefinition. A recent change that added a builtin
prototype to arm_vector_types.h broke the build [1] because int64_t is
defined as 'long' in AArch64TargetInfo, triggering a mismatch error with
the kernel's redefinition.

  In file included from lib/crc/crc64-neon.c:7:
  In file included from arch/arm64/include/asm/neon-intrinsics.h:33:
  In file included from /llvm_prefix/lib/clang/24/include/arm_neon.h:36:
  /llvm_prefix/lib/clang/24/include/arm_vector_types.h:61:66: error: conflicting types for '__arm_set_fpm_lscale'
     61 | __inline__ fpm_t __attribute__((__always_inline__, __nodebug__)) __arm_set_fpm_lscale(fpm_t __fpm, uint64_t __scale);
        |                                                                  ^
  /llvm_prefix/lib/clang/24/include/arm_vector_types.h:61:66: note: '__arm_set_fpm_lscale' is a builtin with type 'unsigned long (unsigned long, unsigned long)'
  /llvm_prefix/lib/clang/24/include/arm_vector_types.h:62:66: error: conflicting types for '__arm_set_fpm_nscale'
     62 | __inline__ fpm_t __attribute__((__always_inline__, __nodebug__)) __arm_set_fpm_nscale(fpm_t __fpm, int64_t __scale);
        |                                                                  ^
  /llvm_prefix/lib/clang/24/include/arm_vector_types.h:62:66: note: '__arm_set_fpm_nscale' is a builtin with type 'unsigned long (unsigned long, long)'
  /llvm_prefix/lib/clang/24/include/arm_vector_types.h:63:67: error: conflicting types for '__arm_set_fpm_lscale2'
     63 | __inline__ fpm_t __attribute__((__always_inline__, __nodebug__))  __arm_set_fpm_lscale2(fpm_t __fpm, uint64_t __scale);
        |                                                                   ^
  /llvm_prefix/lib/clang/24/include/arm_vector_types.h:63:67: note: '__arm_set_fpm_lscale2' is a builtin with type 'unsigned long (unsigned long, unsigned long)'

In a similar manner to existing options that adjust types, add
'-fint64-is-long-long' to force int64_t to be 'long long' in the
compiler, allowing the kernel to include this flag when arm_neon.h is
included. This allows further cleanup of an existing workaround for this
mismatch [2] in addition to resolving the above build error.

Link: https://github.com/llvm/llvm-project/pull/227722#issuecomment-6065215071 [1]
Link: https://git.kernel.org/linus/0738c8b5915c7eaf1e6007b441008e8f3b460443 [2]
Signed-off-by: Nathan Chancellor <nathan at kernel.org>
---
 clang/include/clang/Basic/LangOptions.def | 2 ++
 clang/include/clang/Options/Options.td    | 5 +++++
 clang/lib/Basic/TargetInfo.cpp            | 3 +++
 clang/lib/Driver/ToolChains/Clang.cpp     | 4 ++++
 clang/test/Driver/clang_f_opts.c          | 5 +++++
 5 files changed, 19 insertions(+)

diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def
index 155d365771b836..0ee112e52cd8ce 100644
--- a/clang/include/clang/Basic/LangOptions.def
+++ b/clang/include/clang/Basic/LangOptions.def
@@ -214,6 +214,8 @@ ENUM_LANGOPT(DefaultCallingConv, DefaultCallingConvention, 3, DCC_None, NotCompa
 
 LANGOPT(ShortEnums        , 1, 0, NotCompatible, "short enum types")
 
+LANGOPT(Int64LongLong     , 1, 0, NotCompatible, "type of int64_t is long long")
+
 LANGOPT(OpenCL            , 1, 0, NotCompatible, "OpenCL")
 LANGOPT(OpenCLVersion     , 32, 0, NotCompatible, "OpenCL C version")
 LANGOPT(OpenCLCPlusPlus   , 1, 0, NotCompatible, "C++ for OpenCL")
diff --git a/clang/include/clang/Options/Options.td b/clang/include/clang/Options/Options.td
index bc2d305fc45242..240fdce570acdd 100644
--- a/clang/include/clang/Options/Options.td
+++ b/clang/include/clang/Options/Options.td
@@ -4587,6 +4587,11 @@ defm short_enums : BoolFOption<"short-enums",
           "Allocate to an enum type only as many bytes as it"
            " needs for the declared range of possible values">,
   NegFlag<SetFalse>>;
+defm int64_is_long_long : BoolFOption<"int64-is-long-long",
+  LangOpts<"Int64LongLong">, DefaultFalse,
+  PosFlag<SetTrue, [], [ClangOption, CC1Option],
+          "Force type of int64_t to be long long">,
+  NegFlag<SetFalse>>;
 defm char8__t : BoolFOption<"char8_t",
   LangOpts<"Char8">, Default<cpp20.KeyPath>,
   PosFlag<SetTrue, [], [ClangOption], "Enable">,
diff --git a/clang/lib/Basic/TargetInfo.cpp b/clang/lib/Basic/TargetInfo.cpp
index 6e390226d2e4b8..270f73e8235ad2 100644
--- a/clang/lib/Basic/TargetInfo.cpp
+++ b/clang/lib/Basic/TargetInfo.cpp
@@ -562,6 +562,9 @@ void TargetInfo::adjust(DiagnosticsEngine &Diags, LangOptions &Opts,
     }
   }
 
+  if (Opts.Int64LongLong)
+    Int64Type = SignedLongLong;
+
   if (Opts.NewAlignOverride)
     NewAlign = Opts.NewAlignOverride * getCharWidth();
 
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 454673dd20f9ad..8319302247cafd 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -7619,6 +7619,10 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
                    TC.getArch() == llvm::Triple::hexagon || Triple.isOSzOS()))
     CmdArgs.push_back("-fshort-enums");
 
+  if (Args.hasFlag(options::OPT_fint64_is_long_long,
+                   options::OPT_fno_int64_is_long_long, false))
+    CmdArgs.push_back("-fint64-is-long-long");
+
   RenderCharacterOptions(Args, AuxTriple ? *AuxTriple : RawTriple, CmdArgs);
 
   // -fuse-cxa-atexit is default.
diff --git a/clang/test/Driver/clang_f_opts.c b/clang/test/Driver/clang_f_opts.c
index 9f417c8037c9cb..43738a39144c6c 100644
--- a/clang/test/Driver/clang_f_opts.c
+++ b/clang/test/Driver/clang_f_opts.c
@@ -657,3 +657,8 @@
 // RUN: %clang -### --target=x86_64-pc-windows-msvc -fno-strict-aliasing %s 2>&1 | FileCheck -check-prefix=CHECK-NO-STRICT-ALIASING %s
 // CHECK-STRICT-ALIASING-NOT: -relaxed-aliasing
 // CHECK-NO-STRICT-ALIASING: -relaxed-aliasing
+//
+// RUN: %clang -### -S -fint64-is-long-long %s 2>&1 | FileCheck -check-prefix=CHECK-INT64-IS-LONG-LONG %s
+// RUN: %clang -### -S -fno-int64-is-long-long %s 2>&1 | FileCheck -check-prefix=CHECK-NO-INT64-IS-LONG-LONG %s
+// CHECK-INT64-IS-LONG-LONG: "-fint64-is-long-long"
+// CHECK-NO-INT64-IS-LONG-LONG-NOT: "-fint64-is-long-long"

>From e50a463a7aa0c6ad67fdccfb526d9cb16a385123 Mon Sep 17 00:00:00 2001
From: Nathan Chancellor <nathan at kernel.org>
Date: Thu, 22 Oct 2026 16:50:34 -0700
Subject: [PATCH 2/4] fixup! [clang] Introduce '-fint64-is-long-long'

Add test that int64_t and uint64_t are defined properly with
'-fint64-is-long-long'.

Signed-off-by: Nathan Chancellor <nathan at kernel.org>
---
 clang/test/Preprocessor/stdint.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/clang/test/Preprocessor/stdint.c b/clang/test/Preprocessor/stdint.c
index 5e207f358377c9..a29d22f739f9d7 100644
--- a/clang/test/Preprocessor/stdint.c
+++ b/clang/test/Preprocessor/stdint.c
@@ -1385,6 +1385,12 @@
 // X86_64_LINUX:WINT_MAX_ 4294967295U
 //
 //
+// RUN: %clang_cc1 -E -ffreestanding -triple=x86_64-none-none -fint64-is-long-long %s | FileCheck -check-prefix X86_64_INT64_LONG_LONG %s
+//
+// X86_64_INT64_LONG_LONG:typedef long long int int64_t;
+// X86_64_INT64_LONG_LONG:typedef long long unsigned int uint64_t;
+//
+//
 // RUN: %clang_cc1 -E -ffreestanding -triple=i386-mingw32 %s | FileCheck -check-prefix I386_MINGW32 %s
 //
 // I386_MINGW32:WCHAR_MAX_ 65535

>From 500b8203169d2b11e30251e4ee9135148e2cf90a Mon Sep 17 00:00:00 2001
From: Nathan Chancellor <nathan at kernel.org>
Date: Sat, 24 Oct 2026 08:16:19 -0700
Subject: [PATCH 3/4] fixup! [clang] Introduce '-fint64-is-long-long'

Signed-off-by: Nathan Chancellor <nathan at kernel.org>
---
 clang/docs/ReleaseNotes.md | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index 1ae4ec0d6b6d5a..beee8bc449b7b1 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -383,6 +383,10 @@ documentation](CIR/index.md) for more information regarding ClangIR's status and
   {doc}`Return Address Authentication Hardening <ReturnAddressAuthenticationHardening>`
   for more information.
 
+- Added `-fint64-is-long-long`, which forces `int64_t` to be `long long`. This
+  can be helpful for projects with freestanding environments that define this
+  type differently from the default of the target triple.
+
 ### Deprecated Compiler Flags
 
 ### Modified Compiler Flags

>From d780e5d50e1bc7ff8504deb7f364fd48eb02e9a7 Mon Sep 17 00:00:00 2001
From: Nathan Chancellor <nathan at kernel.org>
Date: Sat, 24 Oct 2026 09:03:27 -0700
Subject: [PATCH 4/4] fixup! [clang] Introduce '-fint64-is-long-long'

Signed-off-by: Nathan Chancellor <nathan at kernel.org>
---
 clang/test/Preprocessor/stdint.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/clang/test/Preprocessor/stdint.c b/clang/test/Preprocessor/stdint.c
index a29d22f739f9d7..a1ec58a60a7674 100644
--- a/clang/test/Preprocessor/stdint.c
+++ b/clang/test/Preprocessor/stdint.c
@@ -1390,6 +1390,13 @@
 // X86_64_INT64_LONG_LONG:typedef long long int int64_t;
 // X86_64_INT64_LONG_LONG:typedef long long unsigned int uint64_t;
 //
+// X86_64_INT64_LONG_LONG:INT64_MAX_ 9223372036854775807LL
+// X86_64_INT64_LONG_LONG:INT64_MIN_ (-9223372036854775807LL -1)
+// X86_64_INT64_LONG_LONG:UINT64_MAX_ 18446744073709551615ULL
+//
+// X86_64_INT64_LONG_LONG:INT64_C_(0) 0LL
+// X86_64_INT64_LONG_LONG:UINT64_C_(0) 0ULL
+//
 //
 // RUN: %clang_cc1 -E -ffreestanding -triple=i386-mingw32 %s | FileCheck -check-prefix I386_MINGW32 %s
 //



More information about the cfe-commits mailing list