Skip to content

Commit 9d3b331

Browse files
pks-tgitster
authored andcommitted
sane-ctype: fix compiler error on Amazon Linux 2
Compiling Git fails on Amazon Linux 2 when using GCC 7.3.1 with the following compiler error: In file included from compat/posix.h:449:0, from git-compat-util.h:26, from daemon.c:3: compat/../sane-ctype.h:29:60: error: expected expression before ']' token #define sane_istest(x,mask) ((sane_ctype[(unsigned char)(x)] & (mask)) != 0) ^ compat/../sane-ctype.h:29:72: error: expected ')' before '!=' token #define sane_istest(x,mask) ((sane_ctype[(unsigned char)(x)] & (mask)) != 0) ^ compat/../sane-ctype.h:29:60: error: expected expression before ']' token #define sane_istest(x,mask) ((sane_ctype[(unsigned char)(x)] & (mask)) != 0) ^ ... lots of similar lines ... compat/../sane-ctype.h:45:50: error: expected declaration specifiers or '...' before numeric constant #define toupper(x) sane_case((unsigned char)(x), 0) ^ /usr/include/ctype.h:142:12: error: expected identifier or '(' before 'int' extern int isascii (int __c) __THROW; ^ compat/../sane-ctype.h:30:26: error: expected ')' before '&' token #define isascii(x) (((x) & ~0x7f) == 0) ^ compat/../sane-ctype.h:30:35: error: expected ')' before '==' token #define isascii(x) (((x) & ~0x7f) == 0) ^ In file included from /usr/include/features.h:423:0, from /usr/include/unistd.h:25, from compat/posix.h:90, from git-compat-util.h:26, from daemon.c:3: compat/../sane-ctype.h:44:30: error: expected declaration specifiers or '...' before '(' token #define tolower(x) sane_case((unsigned char)(x), 0x20) ^ compat/../sane-ctype.h:44:50: error: expected declaration specifiers or '...' before numeric constant #define tolower(x) sane_case((unsigned char)(x), 0x20) ^ compat/../sane-ctype.h:45:30: error: expected declaration specifiers or '...' before '(' token #define toupper(x) sane_case((unsigned char)(x), 0) ^ compat/../sane-ctype.h:45:50: error: expected declaration specifiers or '...' before numeric constant #define toupper(x) sane_case((unsigned char)(x), 0) ^ This error bisect back to 75a044f (git-compat-util.h: split out POSIX-emulating bits, 2025-02-18), where lots of bits got split out of "git-compat-util.h" into a new "compat/posix.h" header. The compiler error isn't immediately obvious, doubly so because the actual errors are ~3x as long as the above snippet. But what happens here is that we transitively include <ctype.h> after we have included our own "sane-ctype.h" header. Consequently, the function declarations that exist in <ctype.h> for isascii(3p) et al will be mangled by our macros of the same type. The result is of course completely broken. It's unclear why this issue only happens on Amazon Linux 2. My guess is that it's either specific to the compiler version or specific to the glibc version. We don't explicitly include <ctypes.h> anywhere, but it's being transitively included. So chances are that later versions of the toolchain reorganized their headers so that <ctypes.h> is not included transitively anymore. Fix the issue by explicitly including <ctype.h> in "sane-ctype.h". This ensures that the header guards will be activated and that any subsequent include of the same header will become a no-op. With this we can then safely override the function declarations with our own macros. Reported-by: Stan Hu <[email protected]> Signed-off-by: Patrick Steinhardt <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent f368df4 commit 9d3b331

File tree

1 file changed

+9
-0
lines changed

1 file changed

+9
-0
lines changed

sane-ctype.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,15 @@
11
#ifndef SANE_CTYPE_H
22
#define SANE_CTYPE_H
33

4+
/*
5+
* Explicitly include <ctype.h> so that its header guards kick in from here on.
6+
* This ensures that the file won't get included after "sane-ctype.h", as that
7+
* would otherwise lead to a compiler error because the function declarations
8+
* for `int isascii(int c)` et al would be mangled by our macros with the same
9+
* name.
10+
*/
11+
#include <ctype.h>
12+
413
/* Sane ctype - no locale, and works with signed chars */
514
#undef isascii
615
#undef isspace

0 commit comments

Comments
 (0)