-
Notifications
You must be signed in to change notification settings - Fork 15.4k
clang/limits.h: Avoid including limits.h twice #120526
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
base: main
Are you sure you want to change the base?
Conversation
|
@llvm/pr-subscribers-clang @llvm/pr-subscribers-backend-x86 Author: YunQiang Su (wzssyqa) ChangesThe limits.h of glibc, aka /usr/include/limits.h file of *-linux-gnu systems, has And in the limits.h for clang, Normally it won't be a problem as the headers is protected by something like To test it, we can do We can see there is Full diff: https://github.com/llvm/llvm-project/pull/120526.diff 1 Files Affected:
diff --git a/clang/lib/Headers/limits.h b/clang/lib/Headers/limits.h
index d08227fe4d3d48..90f01791f857ee 100644
--- a/clang/lib/Headers/limits.h
+++ b/clang/lib/Headers/limits.h
@@ -20,8 +20,9 @@
#endif
/* System headers include a number of constants from POSIX in <limits.h>.
- Include it if we're hosted. */
-#if __STDC_HOSTED__ && __has_include_next(<limits.h>)
+ Include it if we're hosted. The limits.h of glibc uses include_next to
+ include us, we shouldn't include it again. */
+#if __STDC_HOSTED__ && __has_include_next(<limits.h>) && !defined(_LIBC_LIMITS_H_)
#include_next <limits.h>
#endif
|
|
ping |
|
Does this pattern still occur while doing It also doesn't seem correct to have clang's headers depend on the Adding @AaronBallman who will have stronger opinion around this. |
|
I'm confused why this is necessary, we already work around glibc's quirk here: llvm-project/clang/lib/Headers/limits.h Line 18 in a15fedc
which should then hit glibc's header guard here: https://sourceware.org/git/?p=glibc.git;a=blob;f=include/limits.h#l122 |
There are two problems:
|
|
Maybe my brain still isn't engaging after the holidays, but I'm still not seeing why this change is correct. From the point when Clang gets involved:
So as best I can tell, this is basically another variant of the same thing we were already doing to avoid re-including (part of) glibc, which is why I don't see how that helps. I would have expected the changes to be something more along the lines of (before the block where we define but that leads to the question of: why is including musl's |
|
You are right. My patch only fix the first problem: making a unit test of glibc happy.
See: #120673 also. |
If we build It's due to that |
The limits.h of glibc, aka /usr/include/limits.h file of *-linux-gnu systems, has `#include_next <limits.h>`, so the limits.h from clang is included. And in the limits.h for clang, `#include_next <limits.h>` is also used. Normally it won't be a problem as the headers is protected by something like _LIBC_LIMITS_H_, while it may be a problem when we cross-build glibc on a none glibc platform. For example if we build glibc for x86_64-linux-gnu on a x86_64-linux-musl platform. To test it, we can do ``` echo "#include </usr/include/limits.h>" | bin/clang -E -O2 -xc - -MM -H ``` We can see there is ``` . /usr/include/limits.h .. /usr/lib/llvm-19/lib/clang/19/include/limits.h ... /usr/include/limits.h ```
a7e475b to
cc30e98
Compare
Yes and no. It's due to the redefinitions, for sure. But that diagnostic is suppressed in system headers: https://godbolt.org/z/Mb7Kh975f, so I think we need to understand why there's a |
As we are building |
That's the bug then. It needs to include the header as a system header, not a user header. |
Yes. It does. It uses |
Do you get the same behavior when you use |
|
I have a test like with file /*k.c */
#include <limits.h>
CHAR_BIT
/* include/limits.h */
#ifndef _LIBC_LIMITS_H_
#define _LIBC_LIMITS_H_
#include_next <limits.h>
#define CHAR_BIT 9
#endifThe commands emit the same error message |
The limits.h of glibc, aka /usr/include/limits.h file of *-linux-gnu systems, has
#include_next <limits.h>, so the limits.h from clang is included.And in the limits.h for clang,
#include_next <limits.h>is also used.Normally it won't be a problem as the headers is protected by something like
_LIBC_LIMITS_H_, while it may be a problem when we cross-build glibc on a none glibc platform. For example if we build glibc for x86_64-linux-gnu on a x86_64-linux-musl platform.To test it, we can do
We can see there is
It seems that other libc implementations other than glibc don't have this problem.