From 3e8ffa3fc0a854820d1917bffacc29624ff66a85 Mon Sep 17 00:00:00 2001 From: Mark Mentovai Date: Fri, 12 Jun 2026 15:21:35 -0400 Subject: [PATCH] llvm-18, clang-18: fix build with Xcode 27.0b1 (#33111) This backports llvm a558d6560437 and its follow-up 99f296d2a811 to llvm-18. This is necessary to fix a compile failure when building llvm/lib/Target/Hexagon/HexagonRDFOpt.cpp in llvm-18 using the new SDK, which incorporates llvm 55803b8af1e4, placing additional (standard-conforming) requirements on standard comparators. This also backports llvm 38473c5d351d to llvm-18. This is necessary to fix a compile failure when building libcxx/src/random.cpp in clang-18 using the new SDK, which expects libc++ to provide a definition of INFINITY in under conditions that exist during the build. The header changes are visible in the installed packages, so the revisions of llvm-18 and clang-18 are incremented. --- lang/llvm-18/Portfile | 6 +- .../llvm-18/files/0140-llvm-no-cmp-spec.patch | 283 +++++++++ lang/llvm-18/files/0141-infinity_nan.patch | 547 ++++++++++++++++++ 3 files changed, 834 insertions(+), 2 deletions(-) create mode 100644 lang/llvm-18/files/0140-llvm-no-cmp-spec.patch create mode 100644 lang/llvm-18/files/0141-infinity_nan.patch diff --git a/lang/llvm-18/Portfile b/lang/llvm-18/Portfile index 4b6cbf4246d..d0a04af5999 100644 --- a/lang/llvm-18/Portfile +++ b/lang/llvm-18/Portfile @@ -25,9 +25,9 @@ set clang_exe_version ${llvm_version} version ${llvm_version}.1.8 name llvm-${llvm_version} -revision 2 +revision 3 subport mlir-${llvm_version} { revision 0 } -subport clang-${llvm_version} { revision 7 } +subport clang-${llvm_version} { revision 8 } subport lldb-${llvm_version} { revision 2 } subport flang-${llvm_version} { revision 2 } @@ -125,6 +125,8 @@ patchfiles-append \ 0014-Fix-float.h-to-work-on-Snow-Leopard-and-earlier.patch \ 0019-10.6-and-less-use-emulated-TLS-before-10.7.patch \ 0025-lldb-add-defines-needed-for-older-SDKs.patch \ + 0140-llvm-no-cmp-spec.patch \ + 0141-infinity_nan.patch \ 1234-stop-on-linker-error.patch if {${os.platform} eq "darwin" && ${os.major} < 14} { diff --git a/lang/llvm-18/files/0140-llvm-no-cmp-spec.patch b/lang/llvm-18/files/0140-llvm-no-cmp-spec.patch new file mode 100644 index 00000000000..31d2817ada5 --- /dev/null +++ b/lang/llvm-18/files/0140-llvm-no-cmp-spec.patch @@ -0,0 +1,283 @@ +From 800245013f60947c5983c39f79e1d32756fc117c Mon Sep 17 00:00:00 2001 +From: "A. Jiang" +Date: Sun, 28 Sep 2025 21:36:03 +0800 +Subject: [PATCH] [CodeGen] Get rid of incorrect `std` template specializations + (#160804) + +This is a backport of llvm a558d6560437 to release/18.x, with slight +context adjustment due to llvm 356be1a36ecc not being present. + +> This patch renames comparators +> - from `std::equal_to` to +> `llvm::rdf::RegisterRefEqualTo`, and +> - from `std::less` to +> `llvm::rdf::RegisterRefLess`. +> +> The original specializations don't satisfy the requirements for the +> original `std` templates by being stateful and +> non-default-constructible, so they make the program have UB due to C++17 +> [namespace.std]/2, C++20/23 [namespace.std]/5. +> +> > A program may explicitly instantiate a class template defined in the +> standard library only if the declaration +> > - depends on the name of at least one program-defined type, and +> > - the instantiation meets the standard library requirements for the +> original template. + +This also contains a follow-up fix from llvm 99f296d2a811: + +> [CodeGen][test] Fix Buildbot failure due to uninitialized variables (#161085) +> +> Under some options used by LLVM Buildbot, an uninitialized variable +> (recently added to the test suite) caused constant evaluation failure, +> despite the type of that variable is an empty class. +> +> This PR explicitly initializes the variables with `{}` to fix the error. +> Follows-up a558d656043734cc4d02e0a0a12e4c308c28f8c7. +--- + llvm/include/llvm/CodeGen/RDFGraph.h | 2 +- + llvm/include/llvm/CodeGen/RDFRegisters.h | 54 ++++++++++++----------- + llvm/lib/CodeGen/RDFLiveness.cpp | 9 ++-- + llvm/lib/Target/Hexagon/RDFCopy.cpp | 2 +- + llvm/lib/Target/Hexagon/RDFCopy.h | 8 ++-- + llvm/unittests/CodeGen/TypeTraitsTest.cpp | 36 +++++++++++++++ + 6 files changed, 75 insertions(+), 36 deletions(-) + +diff --git a/llvm/include/llvm/CodeGen/RDFGraph.h b/llvm/include/llvm/CodeGen/RDFGraph.h +index cf7344e8c3e7..30c38da96c11 100644 +--- a/llvm/include/llvm/CodeGen/RDFGraph.h ++++ b/llvm/include/llvm/CodeGen/RDFGraph.h +@@ -447,7 +447,7 @@ private: + AllocatorTy MemPool; + }; + +-using RegisterSet = std::set; ++using RegisterSet = std::set; + + struct TargetOperandInfo { + TargetOperandInfo(const TargetInstrInfo &tii) : TII(tii) {} +diff --git a/llvm/include/llvm/CodeGen/RDFRegisters.h b/llvm/include/llvm/CodeGen/RDFRegisters.h +index 7eed0b4e1e7b..c5060f00a088 100644 +--- a/llvm/include/llvm/CodeGen/RDFRegisters.h ++++ b/llvm/include/llvm/CodeGen/RDFRegisters.h +@@ -201,6 +201,33 @@ private: + std::vector AliasInfos; + }; + ++struct RegisterRefEqualTo { ++ constexpr RegisterRefEqualTo(const llvm::rdf::PhysicalRegisterInfo &pri) ++ : PRI(&pri) {} ++ ++ bool operator()(llvm::rdf::RegisterRef A, llvm::rdf::RegisterRef B) const { ++ return PRI->equal_to(A, B); ++ } ++ ++private: ++ // Make it a pointer just in case. See comment in `RegisterRefLess` below. ++ const llvm::rdf::PhysicalRegisterInfo *PRI; ++}; ++ ++struct RegisterRefLess { ++ constexpr RegisterRefLess(const llvm::rdf::PhysicalRegisterInfo &pri) ++ : PRI(&pri) {} ++ ++ bool operator()(llvm::rdf::RegisterRef A, llvm::rdf::RegisterRef B) const { ++ return PRI->less(A, B); ++ } ++ ++private: ++ // Make it a pointer because apparently some versions of MSVC use std::swap ++ // on the comparator object. ++ const llvm::rdf::PhysicalRegisterInfo *PRI; ++}; ++ + struct RegisterAggr { + RegisterAggr(const PhysicalRegisterInfo &pri) + : Units(pri.getTRI().getNumRegUnits()), PRI(pri) {} +@@ -336,18 +363,6 @@ template <> struct hash { + } + }; + +-template <> struct equal_to { +- constexpr equal_to(const llvm::rdf::PhysicalRegisterInfo &pri) : PRI(&pri) {} +- +- bool operator()(llvm::rdf::RegisterRef A, llvm::rdf::RegisterRef B) const { +- return PRI->equal_to(A, B); +- } +- +-private: +- // Make it a pointer just in case. See comment in `less` below. +- const llvm::rdf::PhysicalRegisterInfo *PRI; +-}; +- + template <> struct equal_to { + bool operator()(const llvm::rdf::RegisterAggr &A, + const llvm::rdf::RegisterAggr &B) const { +@@ -355,23 +370,10 @@ template <> struct equal_to { + } + }; + +-template <> struct less { +- constexpr less(const llvm::rdf::PhysicalRegisterInfo &pri) : PRI(&pri) {} +- +- bool operator()(llvm::rdf::RegisterRef A, llvm::rdf::RegisterRef B) const { +- return PRI->less(A, B); +- } +- +-private: +- // Make it a pointer because apparently some versions of MSVC use std::swap +- // on the std::less specialization. +- const llvm::rdf::PhysicalRegisterInfo *PRI; +-}; +- + } // namespace std + + namespace llvm::rdf { +-using RegisterSet = std::set>; ++using RegisterSet = std::set; + } // namespace llvm::rdf + + #endif // LLVM_CODEGEN_RDFREGISTERS_H +diff --git a/llvm/lib/CodeGen/RDFLiveness.cpp b/llvm/lib/CodeGen/RDFLiveness.cpp +index 11f3fedaa5f9..43bfbad39775 100644 +--- a/llvm/lib/CodeGen/RDFLiveness.cpp ++++ b/llvm/lib/CodeGen/RDFLiveness.cpp +@@ -655,8 +655,9 @@ void Liveness::computePhiInfo() { + // defs, cache the result of subtracting these defs from a given register + // ref. + using RefHash = std::hash; +- using RefEqual = std::equal_to; +- using SubMap = std::unordered_map; ++ using RefEqual = RegisterRefEqualTo; ++ using SubMap = ++ std::unordered_map; + std::unordered_map Subs; + auto ClearIn = [](RegisterRef RR, const RegisterAggr &Mid, SubMap &SM) { + if (Mid.empty()) +@@ -873,7 +874,7 @@ void Liveness::computeLiveIns() { + std::vector LV; + for (const MachineBasicBlock::RegisterMaskPair &LI : B.liveins()) + LV.push_back(RegisterRef(LI.PhysReg, LI.LaneMask)); +- llvm::sort(LV, std::less(PRI)); ++ llvm::sort(LV, RegisterRefLess(PRI)); + dbgs() << printMBBReference(B) << "\t rec = {"; + for (auto I : LV) + dbgs() << ' ' << Print(I, DFG); +@@ -883,7 +884,7 @@ void Liveness::computeLiveIns() { + LV.clear(); + for (RegisterRef RR : LiveMap[&B].refs()) + LV.push_back(RR); +- llvm::sort(LV, std::less(PRI)); ++ llvm::sort(LV, RegisterRefLess(PRI)); + dbgs() << "\tcomp = {"; + for (auto I : LV) + dbgs() << ' ' << Print(I, DFG); +diff --git a/llvm/lib/Target/Hexagon/RDFCopy.cpp b/llvm/lib/Target/Hexagon/RDFCopy.cpp +index b26821cd0171..b2c1075244ae 100644 +--- a/llvm/lib/Target/Hexagon/RDFCopy.cpp ++++ b/llvm/lib/Target/Hexagon/RDFCopy.cpp +@@ -109,7 +109,7 @@ bool CopyPropagation::scanBlock(MachineBasicBlock *B) { + for (NodeAddr IA : BA.Addr->members(DFG)) { + if (DFG.IsCode(IA)) { + NodeAddr SA = IA; +- EqualityMap EM(std::less(DFG.getPRI())); ++ EqualityMap EM(RegisterRefLess(DFG.getPRI())); + if (interpretAsCopy(SA.Addr->getCode(), EM)) + recordCopy(SA, EM); + } +diff --git a/llvm/lib/Target/Hexagon/RDFCopy.h b/llvm/lib/Target/Hexagon/RDFCopy.h +index e4fb89892831..92b2c6598265 100644 +--- a/llvm/lib/Target/Hexagon/RDFCopy.h ++++ b/llvm/lib/Target/Hexagon/RDFCopy.h +@@ -25,8 +25,8 @@ class MachineInstr; + namespace rdf { + + struct CopyPropagation { +- CopyPropagation(DataFlowGraph &dfg) : MDT(dfg.getDT()), DFG(dfg), +- RDefMap(std::less(DFG.getPRI())) {} ++ CopyPropagation(DataFlowGraph &dfg) ++ : MDT(dfg.getDT()), DFG(dfg), RDefMap(RegisterRefLess(DFG.getPRI())) {} + + virtual ~CopyPropagation() = default; + +@@ -35,7 +35,7 @@ namespace rdf { + bool trace() const { return Trace; } + DataFlowGraph &getDFG() { return DFG; } + +- using EqualityMap = std::map; ++ using EqualityMap = std::map; + virtual bool interpretAsCopy(const MachineInstr *MI, EqualityMap &EM); + + private: +@@ -45,7 +45,7 @@ namespace rdf { + bool Trace = false; + + // map: register -> (map: stmt -> reaching def) +- std::map> RDefMap; ++ std::map, RegisterRefLess> RDefMap; + // map: statement -> (map: dst reg -> src reg) + std::map CopyMap; + std::vector Copies; +diff --git a/llvm/unittests/CodeGen/TypeTraitsTest.cpp b/llvm/unittests/CodeGen/TypeTraitsTest.cpp +index 0ca4fa4e82c7..c32ae155f7a1 100644 +--- a/llvm/unittests/CodeGen/TypeTraitsTest.cpp ++++ b/llvm/unittests/CodeGen/TypeTraitsTest.cpp +@@ -6,13 +6,16 @@ + // + //===----------------------------------------------------------------------===// + ++#include "llvm/CodeGen/RDFRegisters.h" + #include "llvm/CodeGen/RegisterPressure.h" + #include "llvm/CodeGen/ScheduleDAG.h" + #include "llvm/CodeGen/SelectionDAGNodes.h" + #include "llvm/CodeGen/SlotIndexes.h" + #include "llvm/CodeGen/TargetPassConfig.h" + #include "gtest/gtest.h" ++#include + #include ++#include + + using namespace llvm; + +@@ -24,5 +27,38 @@ static_assert(std::is_trivially_copyable_v, "trivially copyable"); + static_assert(std::is_trivially_copyable_v, "trivially copyable"); + static_assert(std::is_trivially_copyable_v, + "trivially copyable"); ++ ++// https://llvm.org/PR105169 ++// Verify that we won't accidently specialize std::less and std::equal_to in a ++// wrong way. ++// C++17 [namespace.std]/2, C++20/23 [namespace.std]/5: ++// A program may explicitly instantiate a template defined in the standard ++// library only if the declaration ++// - depends on the name of a user-defined type and ++// - the instantiation meets the standard library requirements for the ++// original template. ++template constexpr bool CheckStdCmpRequirements() { ++ // std::less and std::equal_to are literal, default constructible, and ++ // copyable classes. ++ Fn f1{}; ++ auto f2 = f1; ++ auto f3 = std::move(f2); ++ f2 = f3; ++ f2 = std::move(f3); ++ ++ // Properties held on all known implementations, although not guaranteed by ++ // the standard. ++ static_assert(std::is_empty_v); ++ static_assert(std::is_trivially_default_constructible_v); ++ static_assert(std::is_trivially_copyable_v); ++ ++ return true; ++} ++ ++static_assert(CheckStdCmpRequirements>(), ++ "same as the original template"); ++static_assert(CheckStdCmpRequirements>(), ++ "same as the original template"); ++ + #endif + +-- +2.54.0 + diff --git a/lang/llvm-18/files/0141-infinity_nan.patch b/lang/llvm-18/files/0141-infinity_nan.patch new file mode 100644 index 00000000000..1f8d110717f --- /dev/null +++ b/lang/llvm-18/files/0141-infinity_nan.patch @@ -0,0 +1,547 @@ +From c19c836dd2c1d8ca31ba781f3ddd0305c45d1da5 Mon Sep 17 00:00:00 2001 +From: Ian Anderson +Date: Thu, 23 Oct 2025 10:15:00 -0700 +Subject: [PATCH] [clang][headers] Need a way for math.h to share the + definitions of INIFINITY and NAN with float.h (#164348) + +This is a backport of llvm 38473c5d351d to release/18.x, with slight +adjustment due to llvm 0e3fdc222a04, b222fa828432, 0e7590a25cd2, +2f2b931e1296, and df241b19c952 not being present. + +> In C23 mode, both float.h and math.h are required to define INIFINITY +> and NAN. However, with clang modules, there needs to be a single owner +> for the declarations. Let that be float.h since that's the suggested +> true owner in Annex F.2.2 of ISO/IEC 9899:2024, and introduce +> `__need_infinity_nan` so that math.h can pick up the compiler +> definitions. +--- + .../find-all-symbols/STLPostfixHeaderMap.cpp | 3 + + .../clangd/index/CanonicalIncludes.cpp | 3 + + clang/lib/Headers/CMakeLists.txt | 3 + + clang/lib/Headers/__float_float.h | 150 ++++++++++++++++++ + clang/lib/Headers/__float_header_macro.h | 12 ++ + clang/lib/Headers/__float_infinity_nan.h | 20 +++ + clang/lib/Headers/float.h | 146 ++--------------- + clang/lib/Headers/module.modulemap | 18 ++- + clang/test/Headers/floatneeds.c | 41 +++++ + clang/test/Modules/relative-resource-dir.m | 1 + + .../gn/secondary/clang/lib/Headers/BUILD.gn | 3 + + 11 files changed, 266 insertions(+), 134 deletions(-) + create mode 100644 clang/lib/Headers/__float_float.h + create mode 100644 clang/lib/Headers/__float_header_macro.h + create mode 100644 clang/lib/Headers/__float_infinity_nan.h + create mode 100644 clang/test/Headers/floatneeds.c + +diff --git a/clang-tools-extra/clang-include-fixer/find-all-symbols/STLPostfixHeaderMap.cpp b/clang-tools-extra/clang-include-fixer/find-all-symbols/STLPostfixHeaderMap.cpp +index df77bf7ea46d..7529243b02d0 100644 +--- a/clang-tools-extra/clang-include-fixer/find-all-symbols/STLPostfixHeaderMap.cpp ++++ b/clang-tools-extra/clang-include-fixer/find-all-symbols/STLPostfixHeaderMap.cpp +@@ -13,6 +13,9 @@ namespace find_all_symbols { + + const HeaderMapCollector::RegexHeaderMap *getSTLPostfixHeaderMap() { + static const HeaderMapCollector::RegexHeaderMap STLPostfixHeaderMap = { ++ {"include/__float_float.h$", ""}, ++ {"include/__float_header_macro.h$", ""}, ++ {"include/__float_infinity_nan.h$", ""}, + {"include/__stdarg___gnuc_va_list.h$", ""}, + {"include/__stdarg___va_copy.h$", ""}, + {"include/__stdarg_va_arg.h$", ""}, +diff --git a/clang-tools-extra/clangd/index/CanonicalIncludes.cpp b/clang-tools-extra/clangd/index/CanonicalIncludes.cpp +index 42eeba36a80e..59203f95caee 100644 +--- a/clang-tools-extra/clangd/index/CanonicalIncludes.cpp ++++ b/clang-tools-extra/clangd/index/CanonicalIncludes.cpp +@@ -16,6 +16,9 @@ namespace clang { + namespace clangd { + namespace { + const std::pair IncludeMappings[] = { ++ {"include/__float_float.h", ""}, ++ {"include/__float_header_macro.h", ""}, ++ {"include/__float_infinity_nan.h", ""}, + {"include/__stdarg___gnuc_va_list.h", ""}, + {"include/__stdarg___va_copy.h", ""}, + {"include/__stdarg_va_arg.h", ""}, +diff --git a/clang/lib/Headers/CMakeLists.txt b/clang/lib/Headers/CMakeLists.txt +index b9a966be73ee..610b3156007f 100644 +--- a/clang/lib/Headers/CMakeLists.txt ++++ b/clang/lib/Headers/CMakeLists.txt +@@ -4,6 +4,9 @@ + set(core_files + builtins.h + float.h ++ __float_float.h ++ __float_header_macro.h ++ __float_infinity_nan.h + inttypes.h + iso646.h + limits.h +diff --git a/clang/lib/Headers/__float_float.h b/clang/lib/Headers/__float_float.h +new file mode 100644 +index 000000000000..276f9c07279a +--- /dev/null ++++ b/clang/lib/Headers/__float_float.h +@@ -0,0 +1,150 @@ ++/*===---- __float_float.h --------------------------------------------------=== ++ * ++ * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++ * See https://llvm.org/LICENSE.txt for license information. ++ * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++ * ++ *===-----------------------------------------------------------------------=== ++ */ ++ ++#ifndef __CLANG_FLOAT_FLOAT_H ++#define __CLANG_FLOAT_FLOAT_H ++ ++#if (defined(__MINGW32__) || defined(_MSC_VER) || defined(_AIX)) && \ ++ __STDC_HOSTED__ ++ ++/* Undefine anything that we'll be redefining below. */ ++# undef FLT_EVAL_METHOD ++# undef FLT_ROUNDS ++# undef FLT_RADIX ++# undef FLT_MANT_DIG ++# undef DBL_MANT_DIG ++# undef LDBL_MANT_DIG ++#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || \ ++ !defined(__STRICT_ANSI__) || \ ++ (defined(__cplusplus) && __cplusplus >= 201103L) || \ ++ (__STDC_HOSTED__ && defined(_AIX) && defined(_ALL_SOURCE)) ++# undef DECIMAL_DIG ++# endif ++# undef FLT_DIG ++# undef DBL_DIG ++# undef LDBL_DIG ++# undef FLT_MIN_EXP ++# undef DBL_MIN_EXP ++# undef LDBL_MIN_EXP ++# undef FLT_MIN_10_EXP ++# undef DBL_MIN_10_EXP ++# undef LDBL_MIN_10_EXP ++# undef FLT_MAX_EXP ++# undef DBL_MAX_EXP ++# undef LDBL_MAX_EXP ++# undef FLT_MAX_10_EXP ++# undef DBL_MAX_10_EXP ++# undef LDBL_MAX_10_EXP ++# undef FLT_MAX ++# undef DBL_MAX ++# undef LDBL_MAX ++# undef FLT_EPSILON ++# undef DBL_EPSILON ++# undef LDBL_EPSILON ++# undef FLT_MIN ++# undef DBL_MIN ++# undef LDBL_MIN ++#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L) || \ ++ !defined(__STRICT_ANSI__) || \ ++ (defined(__cplusplus) && __cplusplus >= 201703L) || \ ++ (__STDC_HOSTED__ && defined(_AIX) && defined(_ALL_SOURCE)) ++# undef FLT_TRUE_MIN ++# undef DBL_TRUE_MIN ++# undef LDBL_TRUE_MIN ++# undef FLT_DECIMAL_DIG ++# undef DBL_DECIMAL_DIG ++# undef LDBL_DECIMAL_DIG ++# undef FLT_HAS_SUBNORM ++# undef DBL_HAS_SUBNORM ++# undef LDBL_HAS_SUBNORM ++# endif ++#endif ++ ++/* Characteristics of floating point types, C99 5.2.4.2.2 */ ++ ++#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || \ ++ (defined(__cplusplus) && __cplusplus >= 201103L) ++#define FLT_EVAL_METHOD __FLT_EVAL_METHOD__ ++#endif ++#define FLT_ROUNDS (__builtin_flt_rounds()) ++#define FLT_RADIX __FLT_RADIX__ ++ ++#define FLT_MANT_DIG __FLT_MANT_DIG__ ++#define DBL_MANT_DIG __DBL_MANT_DIG__ ++#define LDBL_MANT_DIG __LDBL_MANT_DIG__ ++ ++#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || \ ++ !defined(__STRICT_ANSI__) || \ ++ (defined(__cplusplus) && __cplusplus >= 201103L) || \ ++ (__STDC_HOSTED__ && defined(_AIX) && defined(_ALL_SOURCE)) ++# define DECIMAL_DIG __DECIMAL_DIG__ ++#endif ++ ++#define FLT_DIG __FLT_DIG__ ++#define DBL_DIG __DBL_DIG__ ++#define LDBL_DIG __LDBL_DIG__ ++ ++#define FLT_MIN_EXP __FLT_MIN_EXP__ ++#define DBL_MIN_EXP __DBL_MIN_EXP__ ++#define LDBL_MIN_EXP __LDBL_MIN_EXP__ ++ ++#define FLT_MIN_10_EXP __FLT_MIN_10_EXP__ ++#define DBL_MIN_10_EXP __DBL_MIN_10_EXP__ ++#define LDBL_MIN_10_EXP __LDBL_MIN_10_EXP__ ++ ++#define FLT_MAX_EXP __FLT_MAX_EXP__ ++#define DBL_MAX_EXP __DBL_MAX_EXP__ ++#define LDBL_MAX_EXP __LDBL_MAX_EXP__ ++ ++#define FLT_MAX_10_EXP __FLT_MAX_10_EXP__ ++#define DBL_MAX_10_EXP __DBL_MAX_10_EXP__ ++#define LDBL_MAX_10_EXP __LDBL_MAX_10_EXP__ ++ ++#define FLT_MAX __FLT_MAX__ ++#define DBL_MAX __DBL_MAX__ ++#define LDBL_MAX __LDBL_MAX__ ++ ++#define FLT_EPSILON __FLT_EPSILON__ ++#define DBL_EPSILON __DBL_EPSILON__ ++#define LDBL_EPSILON __LDBL_EPSILON__ ++ ++#define FLT_MIN __FLT_MIN__ ++#define DBL_MIN __DBL_MIN__ ++#define LDBL_MIN __LDBL_MIN__ ++ ++#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L) || \ ++ !defined(__STRICT_ANSI__) || \ ++ (defined(__cplusplus) && __cplusplus >= 201703L) || \ ++ (__STDC_HOSTED__ && defined(_AIX) && defined(_ALL_SOURCE)) ++# define FLT_TRUE_MIN __FLT_DENORM_MIN__ ++# define DBL_TRUE_MIN __DBL_DENORM_MIN__ ++# define LDBL_TRUE_MIN __LDBL_DENORM_MIN__ ++# define FLT_DECIMAL_DIG __FLT_DECIMAL_DIG__ ++# define DBL_DECIMAL_DIG __DBL_DECIMAL_DIG__ ++# define LDBL_DECIMAL_DIG __LDBL_DECIMAL_DIG__ ++# define FLT_HAS_SUBNORM __FLT_HAS_DENORM__ ++# define DBL_HAS_SUBNORM __DBL_HAS_DENORM__ ++# define LDBL_HAS_SUBNORM __LDBL_HAS_DENORM__ ++#endif ++ ++#ifdef __STDC_WANT_IEC_60559_TYPES_EXT__ ++# define FLT16_MANT_DIG __FLT16_MANT_DIG__ ++# define FLT16_DECIMAL_DIG __FLT16_DECIMAL_DIG__ ++# define FLT16_DIG __FLT16_DIG__ ++# define FLT16_MIN_EXP __FLT16_MIN_EXP__ ++# define FLT16_MIN_10_EXP __FLT16_MIN_10_EXP__ ++# define FLT16_MAX_EXP __FLT16_MAX_EXP__ ++# define FLT16_MAX_10_EXP __FLT16_MAX_10_EXP__ ++# define FLT16_MAX __FLT16_MAX__ ++# define FLT16_EPSILON __FLT16_EPSILON__ ++# define FLT16_MIN __FLT16_MIN__ ++# define FLT16_TRUE_MIN __FLT16_TRUE_MIN__ ++#endif /* __STDC_WANT_IEC_60559_TYPES_EXT__ */ ++ ++#endif /* __CLANG_FLOAT_FLOAT_H */ +diff --git a/clang/lib/Headers/__float_header_macro.h b/clang/lib/Headers/__float_header_macro.h +new file mode 100644 +index 000000000000..11b270e90deb +--- /dev/null ++++ b/clang/lib/Headers/__float_header_macro.h +@@ -0,0 +1,12 @@ ++/*===---- __float_header_macro.h -------------------------------------------=== ++ * ++ * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++ * See https://llvm.org/LICENSE.txt for license information. ++ * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++ * ++ *===-----------------------------------------------------------------------=== ++ */ ++ ++#ifndef __CLANG_FLOAT_H ++#define __CLANG_FLOAT_H ++#endif /* __CLANG_FLOAT_H */ +diff --git a/clang/lib/Headers/__float_infinity_nan.h b/clang/lib/Headers/__float_infinity_nan.h +new file mode 100644 +index 000000000000..e3b837318ded +--- /dev/null ++++ b/clang/lib/Headers/__float_infinity_nan.h +@@ -0,0 +1,20 @@ ++/*===---- __float_infinity_nan.h -------------------------------------------=== ++ * ++ * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++ * See https://llvm.org/LICENSE.txt for license information. ++ * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++ * ++ *===-----------------------------------------------------------------------=== ++ */ ++ ++#ifndef __CLANG_FLOAT_INFINITY_NAN_H ++#define __CLANG_FLOAT_INFINITY_NAN_H ++ ++/* C23 5.2.5.3.3p29-30 */ ++#undef INFINITY ++#undef NAN ++ ++#define INFINITY (__builtin_inf()) ++#define NAN (__builtin_nan("")) ++ ++#endif /* __CLANG_FLOAT_INFINITY_NAN_H */ +diff --git a/clang/lib/Headers/float.h b/clang/lib/Headers/float.h +index 0e73bca0a2d6..bcfe7f6dd321 100644 +--- a/clang/lib/Headers/float.h ++++ b/clang/lib/Headers/float.h +@@ -7,9 +7,16 @@ + *===-----------------------------------------------------------------------=== + */ + +-#ifndef __CLANG_FLOAT_H +-#define __CLANG_FLOAT_H ++#if !defined(__need_infinity_nan) ++#define __need_float_float ++#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L) || \ ++ !defined(__STRICT_ANSI__) ++#define __need_infinity_nan ++#endif ++#include <__float_header_macro.h> ++#endif + ++#ifdef __need_float_float + /* If we're on MinGW, fall back to the system's float.h, which might have + * additional definitions provided for Windows. + * For more details see http://msdn.microsoft.com/en-us/library/y0ybw9fy.aspx +@@ -31,138 +38,13 @@ + + # include_next + +-/* Undefine anything that we'll be redefining below. */ +-# undef FLT_EVAL_METHOD +-# undef FLT_ROUNDS +-# undef FLT_RADIX +-# undef FLT_MANT_DIG +-# undef DBL_MANT_DIG +-# undef LDBL_MANT_DIG +-#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || \ +- !defined(__STRICT_ANSI__) || \ +- (defined(__cplusplus) && __cplusplus >= 201103L) || \ +- (__STDC_HOSTED__ && defined(_AIX) && defined(_ALL_SOURCE)) +-# undef DECIMAL_DIG +-# endif +-# undef FLT_DIG +-# undef DBL_DIG +-# undef LDBL_DIG +-# undef FLT_MIN_EXP +-# undef DBL_MIN_EXP +-# undef LDBL_MIN_EXP +-# undef FLT_MIN_10_EXP +-# undef DBL_MIN_10_EXP +-# undef LDBL_MIN_10_EXP +-# undef FLT_MAX_EXP +-# undef DBL_MAX_EXP +-# undef LDBL_MAX_EXP +-# undef FLT_MAX_10_EXP +-# undef DBL_MAX_10_EXP +-# undef LDBL_MAX_10_EXP +-# undef FLT_MAX +-# undef DBL_MAX +-# undef LDBL_MAX +-# undef FLT_EPSILON +-# undef DBL_EPSILON +-# undef LDBL_EPSILON +-# undef FLT_MIN +-# undef DBL_MIN +-# undef LDBL_MIN +-#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L) || \ +- !defined(__STRICT_ANSI__) || \ +- (defined(__cplusplus) && __cplusplus >= 201703L) || \ +- (__STDC_HOSTED__ && defined(_AIX) && defined(_ALL_SOURCE)) +-# undef FLT_TRUE_MIN +-# undef DBL_TRUE_MIN +-# undef LDBL_TRUE_MIN +-# undef FLT_DECIMAL_DIG +-# undef DBL_DECIMAL_DIG +-# undef LDBL_DECIMAL_DIG +-# undef FLT_HAS_SUBNORM +-# undef DBL_HAS_SUBNORM +-# undef LDBL_HAS_SUBNORM +-# endif +-#endif +- +-/* Characteristics of floating point types, C99 5.2.4.2.2 */ +- +-#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || \ +- (defined(__cplusplus) && __cplusplus >= 201103L) +-#define FLT_EVAL_METHOD __FLT_EVAL_METHOD__ + #endif +-#define FLT_ROUNDS (__builtin_flt_rounds()) +-#define FLT_RADIX __FLT_RADIX__ +- +-#define FLT_MANT_DIG __FLT_MANT_DIG__ +-#define DBL_MANT_DIG __DBL_MANT_DIG__ +-#define LDBL_MANT_DIG __LDBL_MANT_DIG__ + +-#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || \ +- !defined(__STRICT_ANSI__) || \ +- (defined(__cplusplus) && __cplusplus >= 201103L) || \ +- (__STDC_HOSTED__ && defined(_AIX) && defined(_ALL_SOURCE)) +-# define DECIMAL_DIG __DECIMAL_DIG__ ++#include <__float_float.h> ++#undef __need_float_float + #endif + +-#define FLT_DIG __FLT_DIG__ +-#define DBL_DIG __DBL_DIG__ +-#define LDBL_DIG __LDBL_DIG__ +- +-#define FLT_MIN_EXP __FLT_MIN_EXP__ +-#define DBL_MIN_EXP __DBL_MIN_EXP__ +-#define LDBL_MIN_EXP __LDBL_MIN_EXP__ +- +-#define FLT_MIN_10_EXP __FLT_MIN_10_EXP__ +-#define DBL_MIN_10_EXP __DBL_MIN_10_EXP__ +-#define LDBL_MIN_10_EXP __LDBL_MIN_10_EXP__ +- +-#define FLT_MAX_EXP __FLT_MAX_EXP__ +-#define DBL_MAX_EXP __DBL_MAX_EXP__ +-#define LDBL_MAX_EXP __LDBL_MAX_EXP__ +- +-#define FLT_MAX_10_EXP __FLT_MAX_10_EXP__ +-#define DBL_MAX_10_EXP __DBL_MAX_10_EXP__ +-#define LDBL_MAX_10_EXP __LDBL_MAX_10_EXP__ +- +-#define FLT_MAX __FLT_MAX__ +-#define DBL_MAX __DBL_MAX__ +-#define LDBL_MAX __LDBL_MAX__ +- +-#define FLT_EPSILON __FLT_EPSILON__ +-#define DBL_EPSILON __DBL_EPSILON__ +-#define LDBL_EPSILON __LDBL_EPSILON__ +- +-#define FLT_MIN __FLT_MIN__ +-#define DBL_MIN __DBL_MIN__ +-#define LDBL_MIN __LDBL_MIN__ +- +-#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L) || \ +- !defined(__STRICT_ANSI__) || \ +- (defined(__cplusplus) && __cplusplus >= 201703L) || \ +- (__STDC_HOSTED__ && defined(_AIX) && defined(_ALL_SOURCE)) +-# define FLT_TRUE_MIN __FLT_DENORM_MIN__ +-# define DBL_TRUE_MIN __DBL_DENORM_MIN__ +-# define LDBL_TRUE_MIN __LDBL_DENORM_MIN__ +-# define FLT_DECIMAL_DIG __FLT_DECIMAL_DIG__ +-# define DBL_DECIMAL_DIG __DBL_DECIMAL_DIG__ +-# define LDBL_DECIMAL_DIG __LDBL_DECIMAL_DIG__ +-# define FLT_HAS_SUBNORM __FLT_HAS_DENORM__ +-# define DBL_HAS_SUBNORM __DBL_HAS_DENORM__ +-# define LDBL_HAS_SUBNORM __LDBL_HAS_DENORM__ ++#ifdef __need_infinity_nan ++#include <__float_infinity_nan.h> ++#undef __need_infinity_nan + #endif +- +-#ifdef __STDC_WANT_IEC_60559_TYPES_EXT__ +-# define FLT16_MANT_DIG __FLT16_MANT_DIG__ +-# define FLT16_DECIMAL_DIG __FLT16_DECIMAL_DIG__ +-# define FLT16_DIG __FLT16_DIG__ +-# define FLT16_MIN_EXP __FLT16_MIN_EXP__ +-# define FLT16_MIN_10_EXP __FLT16_MIN_10_EXP__ +-# define FLT16_MAX_EXP __FLT16_MAX_EXP__ +-# define FLT16_MAX_10_EXP __FLT16_MAX_10_EXP__ +-# define FLT16_MAX __FLT16_MAX__ +-# define FLT16_EPSILON __FLT16_EPSILON__ +-# define FLT16_MIN __FLT16_MIN__ +-# define FLT16_TRUE_MIN __FLT16_TRUE_MIN__ +-#endif /* __STDC_WANT_IEC_60559_TYPES_EXT__ */ +- +-#endif /* __CLANG_FLOAT_H */ +diff --git a/clang/lib/Headers/module.modulemap b/clang/lib/Headers/module.modulemap +index 56a13f69bc05..e9738eb8e737 100644 +--- a/clang/lib/Headers/module.modulemap ++++ b/clang/lib/Headers/module.modulemap +@@ -166,8 +166,22 @@ module _Builtin_intrinsics [system] [extern_c] { + // that module. The system float.h (if present) will be treated + // as a textual header in the sytem module. + module _Builtin_float [system] { +- header "float.h" +- export * ++ textual header "float.h" ++ ++ explicit module float { ++ header "__float_float.h" ++ export * ++ } ++ ++ explicit module header_macro { ++ header "__float_header_macro.h" ++ export * ++ } ++ ++ explicit module infinity_nan { ++ header "__float_infinity_nan.h" ++ export * ++ } + } + + module _Builtin_inttypes [system] { +diff --git a/clang/test/Headers/floatneeds.c b/clang/test/Headers/floatneeds.c +new file mode 100644 +index 000000000000..e544b4100990 +--- /dev/null ++++ b/clang/test/Headers/floatneeds.c +@@ -0,0 +1,41 @@ ++// RUN: rm -fR %t ++// RUN: split-file %s %t ++// RUN: %clang_cc1 -fsyntax-only -verify=c99 -std=c99 %t/floatneeds0.c ++// RUN: %clang_cc1 -fsyntax-only -verify=c99 -std=c99 %t/floatneeds1.c ++// RUN: %clang_cc1 -fsyntax-only -verify=c23 -std=c23 %t/floatneeds0.c ++// RUN: %clang_cc1 -fsyntax-only -verify=c23 -std=c23 %t/floatneeds1.c ++// RUN: %clang_cc1 -fsyntax-only -verify=c99-modules -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -std=c99 %t/floatneeds0.c ++// RUN: %clang_cc1 -fsyntax-only -verify=c99-modules -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -std=c99 %t/floatneeds1.c ++// RUN: %clang_cc1 -fsyntax-only -verify=c23-modules -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -std=c23 %t/floatneeds0.c ++// RUN: %clang_cc1 -fsyntax-only -verify=c23-modules -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -std=c23 %t/floatneeds1.c ++ ++// Use C99 to verify that __need_ can be used to get types that wouldn't normally be available. ++ ++//--- floatneeds0.c ++float infinity0 = INFINITY; // c99-error{{undeclared identifier 'INFINITY'}} c23-error{{undeclared identifier 'INFINITY'}} \ ++ c99-modules-error{{undeclared identifier 'INFINITY'}} c23-modules-error{{undeclared identifier 'INFINITY'}} ++float nan0 = NAN; // c99-error{{undeclared identifier 'NAN'}} c23-error{{undeclared identifier 'NAN'}} \ ++ c99-modules-error{{undeclared identifier 'NAN'}} c23-modules-error{{undeclared identifier 'NAN'}} ++float max0 = FLT_MAX; // c99-error{{undeclared identifier 'FLT_MAX'}} c23-error{{undeclared identifier 'FLT_MAX'}} \ ++ c99-modules-error{{undeclared identifier 'FLT_MAX'}} c23-modules-error{{undeclared identifier 'FLT_MAX'}} ++ ++#define __need_infinity_nan ++#include ++float infinity1 = INFINITY; ++float nan1 = NAN; ++float max1 = FLT_MAX; // c99-error{{undeclared identifier}} c23-error{{undeclared identifier}} \ ++ c99-modules-error{{undeclared identifier}} c23-modules-error{{undeclared identifier}} ++ ++#include ++float infinity2 = INFINITY; ++float nan2 = NAN; ++float max2 = FLT_MAX; ++ ++//--- floatneeds1.c ++// c23-no-diagnostics ++// c23-modules-no-diagnostics ++ ++#include ++float infinity0 = INFINITY; // c99-error{{undeclared identifier}} c99-modules-error{{undeclared identifier}} ++float nan0 = NAN; // c99-error{{undeclared identifier}} c99-modules-error{{undeclared identifier}} ++float max0 = FLT_MAX; +diff --git a/clang/test/Modules/relative-resource-dir.m b/clang/test/Modules/relative-resource-dir.m +index 4f88150a2ba4..f6e2aec4017c 100644 +--- a/clang/test/Modules/relative-resource-dir.m ++++ b/clang/test/Modules/relative-resource-dir.m +@@ -8,5 +8,6 @@ + // RUN: -fimplicit-module-maps -fmodules-cache-path=%t.mcp \ + // RUN: -fbuiltin-headers-in-system-modules \ + // RUN: -resource-dir resource-dir \ ++// RUN: -internal-isystem resource-dir/include \ + // RUN: -emit-module %S/Inputs/builtin-headers/module.modulemap \ + // RUN: -fmodule-name=ModuleWithBuiltinHeader -o %t.pcm +diff --git a/llvm/utils/gn/secondary/clang/lib/Headers/BUILD.gn b/llvm/utils/gn/secondary/clang/lib/Headers/BUILD.gn +index 7c00aaffdc1b..50830a5d0039 100644 +--- a/llvm/utils/gn/secondary/clang/lib/Headers/BUILD.gn ++++ b/llvm/utils/gn/secondary/clang/lib/Headers/BUILD.gn +@@ -103,6 +103,9 @@ copy("Headers") { + "__clang_hip_math.h", + "__clang_hip_runtime_wrapper.h", + "__clang_hip_stdlib.h", ++ "__float_float.h", ++ "__float_header_macro.h", ++ "__float_infinity_nan.h", + "__stdarg___gnuc_va_list.h", + "__stdarg___va_copy.h", + "__stdarg_va_arg.h", +-- +2.54.0 +