Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[libc] Add C23 limits.h header. #78887

Merged
merged 11 commits into from
Jan 24, 2024
Merged

[libc] Add C23 limits.h header. #78887

merged 11 commits into from
Jan 24, 2024

Conversation

lntue
Copy link
Contributor

@lntue lntue commented Jan 21, 2024

No description provided.

@llvmbot
Copy link
Collaborator

llvmbot commented Jan 21, 2024

@llvm/pr-subscribers-libc

Author: None (lntue)

Changes

Full diff: https://github.com/llvm/llvm-project/pull/78887.diff

12 Files Affected:

  • (modified) libc/config/darwin/arm/headers.txt (+1)
  • (modified) libc/config/darwin/x86_64/headers.txt (+1)
  • (modified) libc/config/gpu/headers.txt (+1)
  • (modified) libc/config/linux/aarch64/headers.txt (+1)
  • (modified) libc/config/linux/riscv/headers.txt (+1)
  • (modified) libc/config/linux/x86_64/headers.txt (+1)
  • (modified) libc/include/CMakeLists.txt (+8)
  • (added) libc/include/limits.h.def (+14)
  • (modified) libc/include/llvm-libc-macros/CMakeLists.txt (+6)
  • (modified) libc/include/llvm-libc-macros/float-macros.h (+9)
  • (added) libc/include/llvm-libc-macros/limits-macros.h (+229)
  • (modified) libc/spec/stdc.td (+3)
diff --git a/libc/config/darwin/arm/headers.txt b/libc/config/darwin/arm/headers.txt
index 2dd54b7c1f50535..d80628445af5c52 100644
--- a/libc/config/darwin/arm/headers.txt
+++ b/libc/config/darwin/arm/headers.txt
@@ -4,6 +4,7 @@ set(TARGET_PUBLIC_HEADERS
     libc.include.fenv
     libc.include.float
     libc.include.inttypes
+    libc.include.limits
     libc.include.math
     libc.include.stdlib
     libc.include.string
diff --git a/libc/config/darwin/x86_64/headers.txt b/libc/config/darwin/x86_64/headers.txt
index 510d62688a45fa3..1e81e303ddd6b47 100644
--- a/libc/config/darwin/x86_64/headers.txt
+++ b/libc/config/darwin/x86_64/headers.txt
@@ -5,6 +5,7 @@ set(TARGET_PUBLIC_HEADERS
     #libc.include.fenv
     libc.include.float
     libc.include.inttypes
+    libc.include.limits
     libc.include.math
     libc.include.stdlib
     libc.include.string
diff --git a/libc/config/gpu/headers.txt b/libc/config/gpu/headers.txt
index e68e18b87b10e27..3b04dd89fafe6f7 100644
--- a/libc/config/gpu/headers.txt
+++ b/libc/config/gpu/headers.txt
@@ -4,6 +4,7 @@ set(TARGET_PUBLIC_HEADERS
     libc.include.string
     libc.include.float
     libc.include.inttypes
+    libc.include.limits
     libc.include.math
     libc.include.fenv
     libc.include.time
diff --git a/libc/config/linux/aarch64/headers.txt b/libc/config/linux/aarch64/headers.txt
index 709a8dbdedc98f1..60d978bcaa76e44 100644
--- a/libc/config/linux/aarch64/headers.txt
+++ b/libc/config/linux/aarch64/headers.txt
@@ -6,6 +6,7 @@ set(TARGET_PUBLIC_HEADERS
     libc.include.fenv
     libc.include.float
     libc.include.inttypes
+    libc.include.limits
     libc.include.math
     libc.include.pthread
     libc.include.signal
diff --git a/libc/config/linux/riscv/headers.txt b/libc/config/linux/riscv/headers.txt
index dc1daa48f6c875f..0ade63dc5933b53 100644
--- a/libc/config/linux/riscv/headers.txt
+++ b/libc/config/linux/riscv/headers.txt
@@ -8,6 +8,7 @@ set(TARGET_PUBLIC_HEADERS
     libc.include.fenv
     libc.include.float
     libc.include.inttypes
+    libc.include.limits
     libc.include.math
     libc.include.pthread
     libc.include.sched
diff --git a/libc/config/linux/x86_64/headers.txt b/libc/config/linux/x86_64/headers.txt
index b0e0219a30e673c..d103176897a74a8 100644
--- a/libc/config/linux/x86_64/headers.txt
+++ b/libc/config/linux/x86_64/headers.txt
@@ -8,6 +8,7 @@ set(TARGET_PUBLIC_HEADERS
     libc.include.fenv
     libc.include.float
     libc.include.inttypes
+    libc.include.limits
     libc.include.math
     libc.include.pthread
     libc.include.sched
diff --git a/libc/include/CMakeLists.txt b/libc/include/CMakeLists.txt
index cec8b86516b51f0..89fffd1022758ea 100644
--- a/libc/include/CMakeLists.txt
+++ b/libc/include/CMakeLists.txt
@@ -83,6 +83,14 @@ add_gen_header(
     .llvm-libc-macros.float_macros
 )
 
+add_gen_header(
+  limits
+  DEF_FILE limits.h.def
+  GEN_HDR limits.h
+  DEPENDS
+    .llvm-libc-macros.limits_macros
+)
+
 add_gen_header(
   math
   DEF_FILE math.h.def
diff --git a/libc/include/limits.h.def b/libc/include/limits.h.def
new file mode 100644
index 000000000000000..de5f3490459ed8b
--- /dev/null
+++ b/libc/include/limits.h.def
@@ -0,0 +1,14 @@
+//===-- C standard library header limits.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 LLVM_LIBC_LIMITS_H
+#define LLVM_LIBC_LIMITS_H
+
+#include <llvm-libc-macros/limits-macros.h>
+
+#endif // LLVM_LIBC_LIMITS_H
diff --git a/libc/include/llvm-libc-macros/CMakeLists.txt b/libc/include/llvm-libc-macros/CMakeLists.txt
index d965a6a9443ed2a..96ee29d7327224c 100644
--- a/libc/include/llvm-libc-macros/CMakeLists.txt
+++ b/libc/include/llvm-libc-macros/CMakeLists.txt
@@ -73,6 +73,12 @@ add_macro_header(
     float-macros.h
 )
 
+add_macro_header(
+  limits_macros
+  HDR
+    limits-macros.h
+)
+
 add_macro_header(
   math_macros
   HDR
diff --git a/libc/include/llvm-libc-macros/float-macros.h b/libc/include/llvm-libc-macros/float-macros.h
index 8e4b91b9a0f557d..16ccc8e806617a1 100644
--- a/libc/include/llvm-libc-macros/float-macros.h
+++ b/libc/include/llvm-libc-macros/float-macros.h
@@ -9,8 +9,17 @@
 #ifndef __LLVM_LIBC_MACROS_FLOAT_MACROS_H
 #define __LLVM_LIBC_MACROS_FLOAT_MACROS_H
 
+#ifdef __clang__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wgnu-include-next"
+#endif //__clang__
+
 #include_next <float.h>
 
+#ifdef __clang__
+#pragma GCC diagnostic pop
+#endif //__clang__
+
 #ifndef FLT_RADIX
 #define FLT_RADIX __FLT_RADIX__
 #endif // FLT_RADIX
diff --git a/libc/include/llvm-libc-macros/limits-macros.h b/libc/include/llvm-libc-macros/limits-macros.h
new file mode 100644
index 000000000000000..e561a95bf3a09a0
--- /dev/null
+++ b/libc/include/llvm-libc-macros/limits-macros.h
@@ -0,0 +1,229 @@
+//===-- Definition of macros from limits.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 __LLVM_LIBC_MACROS_LIMITS_MACROS_H
+#define __LLVM_LIBC_MACROS_LIMITS_MACROS_H
+
+#ifdef __clang__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wgnu-include-next"
+#endif // __clang__
+
+#include_next <limits.h>
+
+#ifdef __clang__
+#pragma GCC diagnostic pop
+#endif // __clang__
+
+#ifndef CHAR_BIT
+#ifdef __CHAR_BIT__
+#define CHAR_BIT __CHAR_BIT__
+#else
+#define CHAR_BIT 8
+#endif // __CHAR_BIT__
+#endif // CHAR_BIT
+
+// TODO: define MB_LEN_MAX if missing
+//   clang: MB_LEN_MAX = 1 -
+//   https://github.com/llvm/llvm-project/blob/main/clang/lib/Headers/limits.h#L64
+//   glibc: MB_LEN_MAX = 16 -
+//   https://github.com/lattera/glibc/blob/master/include/limits.h#L32
+
+// *_WIDTH macros
+
+#ifndef CHAR_WIDTH
+#define CHAR_WIDTH CHAR_BIT
+#endif // CHAR_WIDTH
+
+#ifndef SCHAR_WIDTH
+#define SCHAR_WIDTH CHAR_BIT
+#endif // SCHAR_WIDTH
+
+#ifndef UCHAR_WIDTH
+#define UCHAR_WIDTH CHAR_BIT
+#endif // UCHAR_WIDTH
+
+#ifndef SHRT_WIDTH
+#ifdef __SHRT_WIDTH__
+#define SHRT_WIDTH __SHRT_WIDTH__
+#else
+#define SHRT_WIDTH 16
+#endif // __SHRT_WIDTH__
+#endif // SHRT_WIDTH
+
+#ifndef USHRT_WIDTH
+#define USHRT_WIDTH SHRT_WIDTH
+#endif // USHRT_WIDTH
+
+#ifndef INT_WIDTH
+#ifdef __INT_WIDTH__
+#define INT_WIDTH __INT_WIDTH__
+#else
+#define INT_WIDTH 32
+#endif // __INT_WIDTH__
+#endif // INT_WIDTH
+
+#ifndef UINT_WIDTH
+#define UINT_WIDTH INT_WIDTH
+#endif // UINT_WIDTH
+
+#ifndef LONG_WIDTH
+#ifdef __LONG_WIDTH__
+#define LONG_WIDTH __LONG_WIDTH__
+#elif defined(__WORDSIZE)
+#define LONG_WIDTH __WORDSIZE
+#else
+#error "Unknown WORDSIZE to define LONG_WIDTH."
+#endif // __LONG_WIDTH__
+#endif // LONG_WIDTH
+
+#ifndef ULONG_WIDTH
+#define ULONG_WIDTH LONG_WIDTH
+#endif // ULONG_WIDTH
+
+#ifndef LLONG_WIDTH
+#ifdef __LLONG_WIDTH__
+#define LLONG_WIDTH __LLONG_WIDTH__
+#else
+#define LLONG_WIDTH 64
+#endif // __LLONG_WIDTH__
+#endif // LLONG_WIDTH
+
+#ifndef ULLONG_WIDTH
+#define ULLONG_WIDTH LLONG_WIDTH
+#endif // ULLONG_WIDTH
+
+#ifndef BOOL_WIDTH
+#ifdef __BOOL_WIDTH__
+#define BOOL_WIDTH __BOOL_WIDTH__
+#else
+#define BOOL_WIDTH 1
+#endif // __BOOL_WIDTH__
+#endif // BOOL_WIDTH
+
+// *_MAX macros
+
+#ifndef SCHAR_MAX
+#ifdef __SCHAR_MAX__
+#define SCHAR_MAX __SCHAR_MAX__
+#else
+#define SCHAR_MAX 0x7f
+#endif // __SCHAR_MAX__
+#endif // SCHAR_MAX
+
+#ifndef UCHAR_MAX
+#define UCHAR_MAX (SCHAR_MAX * 2 + 1)
+#endif // UCHAR_MAX
+
+#ifndef CHAR_MAX
+#ifdef __CHAR_UNSIGNED__
+#define CHAR_MAX UCHAR_MAX
+#else
+#define CHAR_MAX SCHAR_MAX
+#endif // __CHAR_UNSIGNED__
+#endif // CHAR_MAX
+
+#ifndef SHRT_MAX
+#ifdef __SHRT_MAX__
+#define SHRT_MAX __SHRT_MAX__
+#else
+#define SHRT_MAX 0x7fff
+#endif // __SHRT_MAX__
+#endif // SHRT_MAX
+
+#ifndef USHRT_MAX
+#define USHRT_MAX (SHRT_MAX * 2U + 1U)
+#endif // USHRT_MAX
+
+#ifndef INT_MAX
+#ifdef __INT_MAX__
+#define INT_MAX __INT_MAX__
+#else
+#define INT_MAX (0 ^ (1 << (INT_WIDTH - 1)))
+#endif // __INT_MAX__
+#endif // INT_MAX
+
+#ifndef UINT_MAX
+#define UINT_MAX (~0U)
+#endif // UINT_MAX
+
+#ifndef LONG_MAX
+#ifdef __LONG_MAX__
+#define LONG_MAX __LONG_MAX__
+#else
+#define LONG_MAX (0L ^ (1L << (LONG_WIDTH - 1)))
+#endif // __LONG_MAX__
+#endif // LONG_MAX
+
+#ifndef ULONG_MAX
+#define ULONG_MAX (~0UL)
+#endif // ULONG_MAX
+
+#ifndef LLONG_MAX
+#ifdef __LONG_LONG_MAX__
+#define LLONG_MAX __LONG_LONG_MAX__
+#else
+#define LLONG_MAX (0LL ^ (1LL << (LLONG_WIDTH - 1)))
+#endif // __LONG_LONG_MAX__
+#endif // LLONG_MAX
+
+#ifndef ULLONG_MAX
+#define ULLONG_MAX (~0ULL)
+#endif // ULLONG_MAX
+
+// *_MIN macros
+
+#ifndef SCHAR_MIN
+#define SCHAR_MIN (-SCHAR_MAX - 1)
+#endif // SCHAR_MIN
+
+#ifndef UCHAR_MIN
+#define UCHAR_MIN 0
+#endif // UCHAR_MIN
+
+#ifndef CHAR_MIN
+#ifdef __CHAR_UNSIGNED__
+#define CHAR_MIN UCHAR_MIN
+#else
+#define CHAR_MIN SCHAR_MIN
+#endif // __CHAR_UNSIGNED__
+#endif // CHAR_MIN
+
+#ifndef SHRT_MIN
+#define SHRT_MIN (-SHRT_MAX - 1)
+#endif // SHRT_MIN
+
+#ifndef USHRT_MIN
+#define USHRT_MIN 0U
+#endif // USHRT_MIN
+
+#ifndef INT_MIN
+#define INT_MIN (-INT_MAX - 1)
+#endif // INT_MIN
+
+#ifndef UINT_MIN
+#define UINT_MIN 0U
+#endif // UINT_MIN
+
+#ifndef LONG_MIN
+#define LONG_MIN (-LONG_MAX - 1L)
+#endif // LONG_MIN
+
+#ifndef ULONG_MIN
+#define ULONG_MIN 0UL
+#endif // ULONG_MIN
+
+#ifndef LLONG_MIN
+#define LLONG_MIN (-LLONG_MAX - 1LL)
+#endif // LLONG_MIN
+
+#ifndef ULLONG_MIN
+#define ULLONG_MIN 0ULL
+#endif // ULLONG_MIN
+
+#endif // __LLVM_LIBC_MACROS_FLOAT_MACROS_H
diff --git a/libc/spec/stdc.td b/libc/spec/stdc.td
index 99e9b3ca65ca59b..aa394d6c92f0993 100644
--- a/libc/spec/stdc.td
+++ b/libc/spec/stdc.td
@@ -856,6 +856,8 @@ def StdC : StandardSpec<"stdc"> {
       ]
   >;
 
+  HeaderSpec Limits = HeaderSpec<"limits.h">;
+
   NamedType SigAtomicT = NamedType<"sig_atomic_t">;
   HeaderSpec Signal = HeaderSpec<
       "signal.h",
@@ -1159,6 +1161,7 @@ def StdC : StandardSpec<"stdc"> {
     Errno,
     Fenv,
     Float,
+    Limits,
     Math,
     String,
     StdIO,

@lntue
Copy link
Contributor Author

lntue commented Jan 22, 2024

@petrhosek Do you mind checking if this header is correct for arm32 / riscv32 / baremetal? Can I leave it to you to enable this header for those targets later? Thanks,

@michaelrj-google
Copy link
Contributor

Ideally we wouldn't provide this header, since it's provided by the compiler. I'm not sure this will fix the problem on the gcc bot since this still includes the system's header, which is what is missing the __GLIBC_USE macro.

Copy link
Member

@nickdesaulniers nickdesaulniers left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Putting a hold on this to discuss.

AFAIK, the compiler should be providing these definitions. Under what conditions is this header needed?

@nickdesaulniers
Copy link
Member

/usr/include/limits.h:145:17: error: missing binary operator before token "("

on my system, that file and line 145 use __GLIBC_USE. There's a comment block at the top of that file that says

The GNU C Library is distributed

and later has:

/* Get the compiler's limits.h, which defines almost all the ISO constants.
# include_next <limits.h>

so it seems what's happening is that we have code (somewhere) that is including <limits.h> and getting the glibc header.

Perhaps we need an #include_next <limits.h> under some very specific conditions.

@nickdesaulniers
Copy link
Member

src/__support/CPP/limits.h is including limits.h and getting glibc's limits.h, not the compilers'.

In file included from /usr/local/lib/gcc/x86_64-pc-linux-gnu/12.2.0/include-fixed/limits.h:203,
                 from /usr/local/lib/gcc/x86_64-pc-linux-gnu/12.2.0/include-fixed/syslimits.h:7,
                 from /usr/local/lib/gcc/x86_64-pc-linux-gnu/12.2.0/include-fixed/limits.h:34,
-->              from /home/llvm-libc-buildbot/buildbot-worker/libc-x86_64-debian-fullbuild/libc-x86_64-debian-gcc-fullbuild-dbg/llvm-project/libc/src/__support/CPP/limits.h:16,
                 from /home/llvm-libc-buildbot/buildbot-worker/libc-x86_64-debian-fullbuild/libc-x86_64-debian-gcc-fullbuild-dbg/llvm-project/libc/src/__support/str_to_integer.h:12,
                 from /home/llvm-libc-buildbot/buildbot-worker/libc-x86_64-debian-fullbuild/libc-x86_64-debian-gcc-fullbuild-dbg/llvm-project/libc/src/inttypes/strtoumax.cpp:11:
/usr/include/limits.h:145:17: error: missing binary operator before token "("
  145 | #if __GLIBC_USE (IEC_605

@SchrodingerZhu
Copy link
Contributor

SchrodingerZhu commented Jan 22, 2024

recent GCC does not seem to provide a standalone version of limits.h on my PC: image

@nickdesaulniers
Copy link
Member

recent GCC does not seem to provide a standalone version of limits.h on my PC:
lib/gcc/x86_64-pc-linux-gnu/13.2.1/include/limits.h

^ it's right there. lib/gcc/x86_64-pc-linux-gnu/13.2.1/include/ is in the compiler's default include path.

@SchrodingerZhu
Copy link
Contributor

I see.

libc/include/llvm-libc-macros/limits-macros.h Outdated Show resolved Hide resolved
libc/include/llvm-libc-macros/limits-macros.h Outdated Show resolved Hide resolved
Comment on lines 34 to 40
// Supplement missing macros.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For which compiler/version/env are these macros missing? (Especially since I'd expect these to be provided by the compiler).

Would be good to comment in the source. I'd like to triple check that these are indeed missing in those environments.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Besides some old versions of gcc do not have LLONG_MIN, LLONG_MAX, ULLONG_MAX as in glibc's limits.h comments, there are also C23 new macros *_WIDTH that are only added to both clang and gcc recently. The rest are for completeness.

Copy link
Member

@nickdesaulniers nickdesaulniers Jan 23, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Besides some old versions of gcc do not have LLONG_MIN, LLONG_MAX, ULLONG_MAX as in glibc's limits.h comments

Ah, but do we have to support any of those versions of GCC? If not, I don't think we should add these.

there are also C23 new macros *_WIDTH that are only added to both clang and gcc recently.

Ok, those are fair to retain with a comment //why//.

The rest are for completeness.

Right, but we don't //need// them; they should come from the compiler's resource headers which we should always expect to be able to rely on. If they don't, then I think it would be better to:

  1. allow the build to fail loudly because such preprocessor defines are missing.
  2. add the bare minimum to get the build back to green, with comments/commit messages explaining why.

The thing I worry most about overriding the compiler's resource headers is that we risk getting these wrong, which may lead to hard to diagnose issues, particularly on platforms other than the host machine.

In particular, if any of these are missing, for reasons other than "this is some brand new thing for a new C standard" then I'd prefer not to hide that reason by providing our own definitions of preprocessor macros typically provided by the compiler.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, but we don't //need// them; they should come from the compiler's resource headers which we should always expect to be able to rely on.

Ok, so looking at GCC's resource headers, it seems that GCC only defines LLONG_MIN, LLONG_MAX and ULLONG_MAX if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L which I think is a problem for C++, and our libc/test/src/__support/CPP/limits_test.cpp which references those. So those are the minimum we may want to just define ourselves.

Comment on lines 23 to 25
// The system's limits.h may, in turn, try to #include_next GCC's limits.h when
// building with GCC.
// Define the macro _GCC_LIMITS_H_ to stop its chains of #include_next.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's the other way around. It's gcc's limits.h which includes gcc's syslimits.h which reincluded gcc's limits.h which finally include_next's glibc's limits.h which is the problem. I would reword this as:

Prevent GCC from including glibc's limits.h.


For reference the include chain looks like:

In file included:
(GLIBC) from /usr/include/limits.h:26,
(GCC) from /usr/lib/gcc/x86_64-linux-gnu/13/include/limits.h:205,
(GCC) from /usr/lib/gcc/x86_64-linux-gnu/13/include/syslimits.h:7,
(GCC) from /usr/lib/gcc/x86_64-linux-gnu/13/include/limits.h:34,
(LLVMLIBC) from /android0/llvm-project/libc/src/__support/CPP/limits.h:16,

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bumping this thread. I still think the comment need to be updated (or my understanding corrected).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the current state of those limits.h headers is messy, I just remove the #include_next <limits.h>, only use compiler supplied macros __INT_MAX__ and friends, and filling in the rest of C23 limits.h macros if missing.

libc/include/llvm-libc-macros/limits-macros.h Outdated Show resolved Hide resolved
@nickdesaulniers
Copy link
Member

nickdesaulniers commented Jan 23, 2024

FWIW, I was able to get the GCC build back to green with just:

diff --git a/libc/src/__support/CPP/limits.h b/libc/src/__support/CPP/limits.h
index d9e7090a0b7b..3c5074a15132 100644
--- a/libc/src/__support/CPP/limits.h
+++ b/libc/src/__support/CPP/limits.h
@@ -13,6 +13,9 @@
 #include "src/__support/CPP/type_traits/is_signed.h"
 #include "src/__support/macros/attributes.h" // LIBC_INLINE
 
+#ifndef __clang__
+#define _LIBC_LIMITS_H_
+#endif
 #include <limits.h> // CHAR_BIT
 
 namespace LIBC_NAMESPACE {
diff --git a/libc/src/time/mktime.cpp b/libc/src/time/mktime.cpp
index e57565f0d1fe..83d55e0000ba 100644
--- a/libc/src/time/mktime.cpp
+++ b/libc/src/time/mktime.cpp
@@ -10,6 +10,9 @@
 #include "src/__support/common.h"
 #include "src/time/time_utils.h"
 
+#ifndef __clang__
+#define _LIBC_LIMITS_H_
+#endif
 #include <limits.h>
 
 namespace LIBC_NAMESPACE {
diff --git a/libc/src/time/time_utils.cpp b/libc/src/time/time_utils.cpp
index 199a74cb168a..9a8a3049374a 100644
--- a/libc/src/time/time_utils.cpp
+++ b/libc/src/time/time_utils.cpp
@@ -9,6 +9,9 @@
 #include "src/time/time_utils.h"
 #include "src/__support/common.h"
 
+#ifndef __clang__
+#define _LIBC_LIMITS_H_
+#endif
 #include <limits.h>
 
 namespace LIBC_NAMESPACE {

I think we could provide our own limits.h (as you do here) and just do that one define if not clang; then require all TUs to include our limits.h, not <limits.h> since it's a tangly mess of include_next for different compiler's resource headers.

EDIT: some unit tests need fixes, too.

EDIT2: #79211

namespace LIBC_NAMESPACE {
namespace cpp {

// Some older gcc distributions don't define these for 32 bit targets.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any information on when this was fixed, such as a specific version of GCC?

Especially since this is src/ so we don't need to support versions of GCC older than gcc-11.

I'd be curious how many of the fallbacks you could remove to satisfy the build with GCC; I suspect not all of the definitions are necessary.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would defer this question to @michaelrj-google who encountered the issue.

#define _GCC_LIMITS_H_
#endif

// Include compiler's header
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you confirm that this is the compiler's header?

I guess I would have thought that #include <limits.h> is the compiler's header, so #include_next <limits.h> is...perhaps /usr/include/limits.h which would be from glibc. The -H compiler flag can give you a very verbose output about the chain of includes.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Drop #include_next <limits.h> to get out of these messy chains of header inclusion.

Comment on lines 23 to 25
// The system's limits.h may, in turn, try to #include_next GCC's limits.h when
// building with GCC.
// Define the macro _GCC_LIMITS_H_ to stop its chains of #include_next.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bumping this thread. I still think the comment need to be updated (or my understanding corrected).

Comment on lines +177 to +184
# `*.__copied_hdr__` is created only to copy the header files to the target
# location, not to be linked against.
set(link_lib "")
foreach(dep ${ADD_HEADER_DEPENDS})
if (NOT dep MATCHES "__copied_hdr__")
list(APPEND link_lib ${dep})
endif()
endforeach()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question: is this exposing your newly added limits.h to the consumers of llvm-libc?

Copy link
Contributor Author

@lntue lntue Jan 24, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No it's not. It just removes those extra command-only targets from getting linked. We won't add limits.h to the consumers, only the "internal" include/llvm-libc-macros/limit-macros.h.

@lntue lntue changed the title [libc] Add limits.h header. [libc] Add C23 limits.h header. Jan 24, 2024
@lntue lntue merged commit 72ce629 into llvm:main Jan 24, 2024
4 checks passed
@lntue lntue deleted the limit branch January 24, 2024 21:09
nickdesaulniers added a commit to nickdesaulniers/llvm-project that referenced this pull request Mar 11, 2024
My GCC build is failing with issues similar why we added our own.  Looks like
we missed one spot. See also:

commit 72ce629 ("[libc] Add C23 limits.h header. (llvm#78887)")
nickdesaulniers added a commit that referenced this pull request Mar 12, 2024
My GCC build is failing with issues similar why we added our own. Looks
like
we missed one spot. See also:

commit 72ce629 ("[libc] Add C23 limits.h header. (#78887)")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants