{"thread":{"id":"63778","subject":"[PATCH RESEND] sane-ctype: fix compiler error on Amazon Linux 2","startedAt":"2025-07-10T09:12:53Z","lastAt":"2025-07-11T15:11:27Z","messageCount":7,"participants":["Patrick Steinhardt","Toon Claes","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"521746","messageId":"20250710-pks-ctype-v1-1-1db7e7568ea2@pks.im","threadId":"63778","inReplyTo":null,"subject":"[PATCH RESEND] sane-ctype: fix compiler error on Amazon Linux 2","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2025-07-10T09:12:40Z","receivedAt":"2025-07-10T09:12:53Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"Compiling Git fails on Amazon Linux 2 when using GCC 7.3.1 with the\nfollowing compiler error:\n\n    In file included from compat/posix.h:449:0,\n                     from git-compat-util.h:26,\n                     from daemon.c:3:\n    compat/../sane-ctype.h:29:60: error: expected expression before ']' token\n     #define sane_istest(x,mask) ((sane_ctype[(unsigned char)(x)] & (mask)) != 0)\n                                                                ^\n    compat/../sane-ctype.h:29:72: error: expected ')' before '!=' token\n     #define sane_istest(x,mask) ((sane_ctype[(unsigned char)(x)] & (mask)) != 0)\n                                                                            ^\n    compat/../sane-ctype.h:29:60: error: expected expression before ']' token\n     #define sane_istest(x,mask) ((sane_ctype[(unsigned char)(x)] & (mask)) != 0)\n                                                                ^\n    ... lots of similar lines ...\n\n    compat/../sane-ctype.h:45:50: error: expected declaration specifiers or '...' before numeric constant\n     #define toupper(x) sane_case((unsigned char)(x), 0)\n                                                      ^\n    /usr/include/ctype.h:142:12: error: expected identifier or '(' before 'int'\n     extern int isascii (int __c) __THROW;\n                ^\n    compat/../sane-ctype.h:30:26: error: expected ')' before '&' token\n     #define isascii(x) (((x) & ~0x7f) == 0)\n                              ^\n    compat/../sane-ctype.h:30:35: error: expected ')' before '==' token\n     #define isascii(x) (((x) & ~0x7f) == 0)\n                                       ^\n    In file included from /usr/include/features.h:423:0,\n                     from /usr/include/unistd.h:25,\n                     from compat/posix.h:90,\n                     from git-compat-util.h:26,\n                     from daemon.c:3:\n    compat/../sane-ctype.h:44:30: error: expected declaration specifiers or '...' before '(' token\n     #define tolower(x) sane_case((unsigned char)(x), 0x20)\n                                  ^\n    compat/../sane-ctype.h:44:50: error: expected declaration specifiers or '...' before numeric constant\n     #define tolower(x) sane_case((unsigned char)(x), 0x20)\n                                                      ^\n    compat/../sane-ctype.h:45:30: error: expected declaration specifiers or '...' before '(' token\n     #define toupper(x) sane_case((unsigned char)(x), 0)\n                                  ^\n    compat/../sane-ctype.h:45:50: error: expected declaration specifiers or '...' before numeric constant\n     #define toupper(x) sane_case((unsigned char)(x), 0)\n                                                      ^\n\nThis error bisect back to 75a044f748 (git-compat-util.h: split out\nPOSIX-emulating bits, 2025-02-18), where lots of bits got split out of\n\"git-compat-util.h\" into a new \"compat/posix.h\" header.\n\nThe compiler error isn't immediately obvious, doubly so because the\nactual errors are ~3x as long as the above snippet. But what happens\nhere is that we transitively include <ctype.h> after we have included\nour own \"sane-ctype.h\" header. Consequently, the function declarations\nthat exist in <ctype.h> for isascii(3p) et al will be mangled by our\nmacros of the same type. The result is of course completely broken.\n\nIt's unclear why this issue only happens on Amazon Linux 2. My guess is\nthat it's either specific to the compiler version or specific to the\nglibc version. We don't explicitly include <ctypes.h> anywhere, but it's\nbeing transitively included. So chances are that later versions of the\ntoolchain reorganized their headers so\n"},{"id":"521747","messageId":"aG-EfIfyXxmS_x22@pks.im","threadId":"63778","inReplyTo":"20250710-pks-ctype-v1-1-1db7e7568ea2@pks.im","subject":"Re: [PATCH RESEND] sane-ctype: fix compiler error on Amazon Linux 2","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2025-07-10T09:14:36Z","receivedAt":"2025-07-10T09:14:42Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Thu, Jul 10, 2025 at 11:12:40AM +0200, Patrick Steinhardt wrote:\n> Compiling Git fails on Amazon Linux 2 when using GCC 7.3.1 with the\n> following compiler error:\n> \n>     In file included from compat/posix.h:449:0,\n>                      from git-compat-util.h:26,\n>                      from daemon.c:3:\n>     compat/../sane-ctype.h:29:60: error: expected expression before ']' token\n>      #define sane_istest(x,mask) ((sane_ctype[(unsigned char)(x)] & (mask)) != 0)\n>                                                                 ^\n>     compat/../sane-ctype.h:29:72: error: expected ')' before '!=' token\n>      #define sane_istest(x,mask) ((sane_ctype[(unsigned char)(x)] & (mask)) != 0)\n>                                                                             ^\n>     compat/../sane-ctype.h:29:60: error: expected expression before ']' token\n>      #define sane_istest(x,mask) ((sane_ctype[(unsigned char)(x)] & (mask)) != 0)\n>                                                                 ^\n>     ... lots of similar lines ...\n> \n>     compat/../sane-ctype.h:45:50: error: expected declaration specifiers or '...' before numeric constant\n>      #define toupper(x) sane_case((unsigned char)(x), 0)\n>                                                       ^\n>     /usr/include/ctype.h:142:12: error: expected identifier or '(' before 'int'\n>      extern int isascii (int __c) __THROW;\n>                 ^\n>     compat/../sane-ctype.h:30:26: error: expected ')' before '&' token\n>      #define isascii(x) (((x) & ~0x7f) == 0)\n>                               ^\n>     compat/../sane-ctype.h:30:35: error: expected ')' before '==' token\n>      #define isascii(x) (((x) & ~0x7f) == 0)\n>                                        ^\n>     In file included from /usr/include/features.h:423:0,\n>                      from /usr/include/unistd.h:25,\n>                      from compat/posix.h:90,\n>                      from git-compat-util.h:26,\n>                      from daemon.c:3:\n>     compat/../sane-ctype.h:44:30: error: expected declaration specifiers or '...' before '(' token\n>      #define tolower(x) sane_case((unsigned char)(x), 0x20)\n>                                   ^\n>     compat/../sane-ctype.h:44:50: error: expected declaration specifiers or '...' before numeric constant\n>      #define tolower(x) sane_case((unsigned char)(x), 0x20)\n>                                                       ^\n>     compat/../sane-ctype.h:45:30: error: expected declaration specifiers or '...' before '(' token\n>      #define toupper(x) sane_case((unsigned char)(x), 0)\n>                                   ^\n>     compat/../sane-ctype.h:45:50: error: expected declaration specifiers or '...' before numeric constant\n>      #define toupper(x) sane_case((unsigned char)(x), 0)\n>                                                       ^\n> \n> This error bisect back to 75a044f748 (git-compat-util.h: split out\n> POSIX-emulating bits, 2025-02-18), where lots of bits got split out of\n> \"git-compat-util.h\" into a new \"compat/posix.h\" header.\n> \n> The compiler error isn't immediately obvious, doubly so because the\n> actual errors are ~3x as long as the above snippet. But what happens\n> here is that we transitively include <ctype.h> after we have included\n> our own \"sane-ctype.h\" header. Consequently, the function declarations\n> that exist in <ctype.h> for isascii(3p) et al will be mangled by our\n> macros of the same type. The result is of course completely broken.\n> \n> It's unclear why this issue only happens on Amazon Linux 2. My guess is\n> that it's either specific to the compiler version or specific to the\n> glibc version. We don't explicitly include <ctypes.h> anywhere, but it's\n> being transitively included. So chances are that later versions of the\n> toolchain reorganized their headers so\n\nHrmpf, what's going on here? Both this email and the first one at [1]\nare getting truncated... I'll debug.\n\nPatrick\n\n[1]: <20250710-pks-ctype-v1-1-c668b308d628@pks.im>\n"},{"id":"521748","messageId":"aG-HMnO11lCYgPiY@pks.im","threadId":"63778","inReplyTo":"aG-EfIfyXxmS_x22@pks.im","subject":"Re: [PATCH RESEND] sane-ctype: fix compiler error on Amazon Linux 2","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2025-07-10T09:26:10Z","receivedAt":"2025-07-10T09:26:16Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Thu, Jul 10, 2025 at 11:14:36AM +0200, Patrick Steinhardt wrote:\n> On Thu, Jul 10, 2025 at 11:12:40AM +0200, Patrick Steinhardt wrote:\n> > Compiling Git fails on Amazon Linux 2 when using GCC 7.3.1 with the\n> > following compiler error:\n> > \n> >     In file included from compat/posix.h:449:0,\n> >                      from git-compat-util.h:26,\n> >                      from daemon.c:3:\n> >     compat/../sane-ctype.h:29:60: error: expected expression before ']' token\n> >      #define sane_istest(x,mask) ((sane_ctype[(unsigned char)(x)] & (mask)) != 0)\n> >                                                                 ^\n> >     compat/../sane-ctype.h:29:72: error: expected ')' before '!=' token\n> >      #define sane_istest(x,mask) ((sane_ctype[(unsigned char)(x)] & (mask)) != 0)\n> >                                                                             ^\n> >     compat/../sane-ctype.h:29:60: error: expected expression before ']' token\n> >      #define sane_istest(x,mask) ((sane_ctype[(unsigned char)(x)] & (mask)) != 0)\n> >                                                                 ^\n> >     ... lots of similar lines ...\n> > \n> >     compat/../sane-ctype.h:45:50: error: expected declaration specifiers or '...' before numeric constant\n> >      #define toupper(x) sane_case((unsigned char)(x), 0)\n> >                                                       ^\n> >     /usr/include/ctype.h:142:12: error: expected identifier or '(' before 'int'\n> >      extern int isascii (int __c) __THROW;\n> >                 ^\n> >     compat/../sane-ctype.h:30:26: error: expected ')' before '&' token\n> >      #define isascii(x) (((x) & ~0x7f) == 0)\n> >                               ^\n> >     compat/../sane-ctype.h:30:35: error: expected ')' before '==' token\n> >      #define isascii(x) (((x) & ~0x7f) == 0)\n> >                                        ^\n> >     In file included from /usr/include/features.h:423:0,\n> >                      from /usr/include/unistd.h:25,\n> >                      from compat/posix.h:90,\n> >                      from git-compat-util.h:26,\n> >                      from daemon.c:3:\n> >     compat/../sane-ctype.h:44:30: error: expected declaration specifiers or '...' before '(' token\n> >      #define tolower(x) sane_case((unsigned char)(x), 0x20)\n> >                                   ^\n> >     compat/../sane-ctype.h:44:50: error: expected declaration specifiers or '...' before numeric constant\n> >      #define tolower(x) sane_case((unsigned char)(x), 0x20)\n> >                                                       ^\n> >     compat/../sane-ctype.h:45:30: error: expected declaration specifiers or '...' before '(' token\n> >      #define toupper(x) sane_case((unsigned char)(x), 0)\n> >                                   ^\n> >     compat/../sane-ctype.h:45:50: error: expected declaration specifiers or '...' before numeric constant\n> >      #define toupper(x) sane_case((unsigned char)(x), 0)\n> >                                                       ^\n> > \n> > This error bisect back to 75a044f748 (git-compat-util.h: split out\n> > POSIX-emulating bits, 2025-02-18), where lots of bits got split out of\n> > \"git-compat-util.h\" into a new \"compat/posix.h\" header.\n> > \n> > The compiler error isn't immediately obvious, doubly so because the\n> > actual errors are ~3x as long as the above snippet. But what happens\n> > here is that we transitively include <ctype.h> after we have included\n> > our own \"sane-ctype.h\" header. Consequently, the function declarations\n> > that exist in <ctype.h> for isascii(3p) et al will be mangled by our\n> > macros of the same type. The result is of course completely broken.\n> > \n> > It's unclear why this issue only happens on Amazon Linux 2. My guess is\n> > that it's either specific to the compiler version or specific to the\n> > glibc version. We don't explicitly include <ctypes.h> anywhere, but it's\n> > being transitively included. So chances are that later versions of the\n> > toolchain reorganized their headers so\n> \n> Hrmpf, what's going on here? Both this email and the first one at [1]\n> are getting truncated... I'll debug.\n\nI've tested with multiple other recipients, works alright there. No\ntruncation, the mail comes through as expected. I'm a bit clueless right\nnow. Konstantin, do you have any idea why this might have happened?\n\nMeanwhile, I'll include the patch as an attachment.\n\nPatrick\n\n\nFrom fabacc9bc7ef7d462d1c7198d5edc18c76b82270 Mon Sep 17 00:00:00 2001\nMessage-ID: <fabacc9bc7ef7d462d1c7198d5edc18c76b82270.1752139420.git.ps@pks.im>\nFrom: Patrick Steinhardt <ps@pks.im>\nDate: Thu, 10 Jul 2025 08:46:27 +0200\nSubject: [PATCH] sane-ctype: fix compiler error on Amazon Linux 2\n\nCompiling Git fails on Amazon Linux 2 when using GCC 7.3.1 with the\nfollowing compiler error:\n\n    In file included from compat/posix.h:449:0,\n                     from git-compat-util.h:26,\n                     from daemon.c:3:\n    compat/../sane-ctype.h:29:60: error: expected expression before ']' token\n     #define sane_istest(x,mask) ((sane_ctype[(unsigned char)(x)] & (mask)) != 0)\n                                                                ^\n    compat/../sane-ctype.h:29:72: error: expected ')' before '!=' token\n     #define sane_istest(x,mask) ((sane_ctype[(unsigned char)(x)] & (mask)) != 0)\n                                                                            ^\n    compat/../sane-ctype.h:29:60: error: expected expression before ']' token\n     #define sane_istest(x,mask) ((sane_ctype[(unsigned char)(x)] & (mask)) != 0)\n                                                                ^\n    ... lots of similar lines ...\n\n    compat/../sane-ctype.h:45:50: error: expected declaration specifiers or '...' before numeric constant\n     #define toupper(x) sane_case((unsigned char)(x), 0)\n                                                      ^\n    /usr/include/ctype.h:142:12: error: expected identifier or '(' before 'int'\n     extern int isascii (int __c) __THROW;\n                ^\n    compat/../sane-ctype.h:30:26: error: expected ')' before '&' token\n     #define isascii(x) (((x) & ~0x7f) == 0)\n                              ^\n    compat/../sane-ctype.h:30:35: error: expected ')' before '==' token\n     #define isascii(x) (((x) & ~0x7f) == 0)\n                                       ^\n    In file included from /usr/include/features.h:423:0,\n                     from /usr/include/unistd.h:25,\n                     from compat/posix.h:90,\n                     from git-compat-util.h:26,\n                     from daemon.c:3:\n    compat/../sane-ctype.h:44:30: error: expected declaration specifiers or '...' before '(' token\n     #define tolower(x) sane_case((unsigned char)(x), 0x20)\n                                  ^\n    compat/../sane-ctype.h:44:50: error: expected declaration specifiers or '...' before numeric constant\n     #define tolower(x) sane_case((unsigned char)(x), 0x20)\n                                                      ^\n    compat/../sane-ctype.h:45:30: error: expected declaration specifiers or '...' before '(' token\n     #define toupper(x) sane_case((unsigned char)(x), 0)\n                                  ^\n    compat/../sane-ctype.h:45:50: error: expected declaration specifiers or '...' before numeric constant\n     #define toupper(x) sane_case((unsigned char)(x), 0)\n                                                      ^\n\nThis error bisect back to 75a044f748 (git-compat-util.h: split out\nPOSIX-emulating bits, 2025-02-18), where lots of bits got split out of\n\"git-compat-util.h\" into a new \"compat/posix.h\" header.\n\nThe compiler error isn't immediately obvious, doubly so because the\nactual errors are ~3x as long as the above snippet. But what happens\nhere is that we transitively include <ctype.h> after we have included\nour own \"sane-ctype.h\" header. Consequently, the function declarations\nthat exist in <ctype.h> for isascii(3p) et al will be mangled by our\nmacros of the same type. The result is of course completely broken.\n\nIt's unclear why this issue only happens on Amazon Linux 2. My guess is\nthat it's either specific to the compiler version or specific to the\nglibc version. We don't explicitly include <ctypes.h> anywhere, but it's\nbeing transitively included. So chances are that later versions of the\ntoolchain reorganized their headers so that <ctypes.h> is not included\ntransitively anymore.\n\nFix the issue by explicitly including <ctype.h> in \"sane-ctype.h\". This\nensures that the header guards will be activated and that any subsequent\ninclude of the same header will become a no-op. With this we can then\nsafely override the function declarations with our own macros.\n\nReported-by: Stan Hu <stanhu@gmail.com>\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n sane-ctype.h | 9 +++++++++\n 1 file changed, 9 insertions(+)\n\ndiff --git a/sane-ctype.h b/sane-ctype.h\nindex cbea1b299b7..4f476c43816 100644\n--- a/sane-ctype.h\n+++ b/sane-ctype.h\n@@ -1,6 +1,15 @@\n #ifndef SANE_CTYPE_H\n #define SANE_CTYPE_H\n \n+/*\n+ * Explicitly include <ctype.h> so that its header guards kick in from here on.\n+ * This ensures that the file won't get included after \"sane-ctype.h\", as that\n+ * would otherwise lead to a compiler error because the function declarations\n+ * for `int isascii(int c)` et al would be mangled by our macros with the same\n+ * name.\n+ */\n+#include <ctype.h>\n+\n /* Sane ctype - no locale, and works with signed chars */\n #undef isascii\n #undef isspace\n-- \n2.50.1.337.g200b4b24a8.dirty\n\n"},{"id":"521749","messageId":"87ldowcpt7.fsf@iotcl.com","threadId":"63778","inReplyTo":"aG-HMnO11lCYgPiY@pks.im","subject":"Re: [PATCH RESEND] sane-ctype: fix compiler error on Amazon Linux 2","fromName":"Toon Claes","fromEmail":"toon@iotcl.com","sentAt":"2025-07-10T10:17:56Z","receivedAt":"2025-07-10T10:18:11Z","isPatch":true,"sender":{"key":"toon@iotcl.com","avatar":"https://avatars.githubusercontent.com/u/121621?v=4"},"body":"Patrick Steinhardt <ps@pks.im> writes:\n\n> Meanwhile, I'll include the patch as an attachment.\n\nI have tested the patch on the Docker image we saw the failure on and\nthis patch fixes the issue.\n\nIf anyone is curious, on that system <ctype.h> is included through:\n\n    In file included from /usr/include/openssl/kssl.h:72:0,\n                     from /usr/include/openssl/ssl.h:165,\n                     from git-compat-util.h:226\n\nDoesn't matter much, because the patch makes sense to me.\n\n-- \nCheers,\nToon\n"},{"id":"521774","messageId":"xmqqtt3j69r8.fsf@gitster.g","threadId":"63778","inReplyTo":"aG-HMnO11lCYgPiY@pks.im","subject":"Re: [PATCH RESEND] sane-ctype: fix compiler error on Amazon Linux 2","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2025-07-10T21:01:15Z","receivedAt":"2025-07-10T21:01:18Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Patrick Steinhardt <ps@pks.im> writes:\n\n>> > This error bisect back to 75a044f748 (git-compat-util.h: split out\n>> > POSIX-emulating bits, 2025-02-18), where lots of bits got split out of\n>> > \"git-compat-util.h\" into a new \"compat/posix.h\" header.\n\nSo there was a subtle change in the inclusion order or something,\ni.e. we used to include <sane-ctype.h> a lot earlier as part of the\n<git-compat-util.h> that tightly controls inclusion order exactly to\navoid this kind of problems, but that has eroded recently?\n\nIn any case, it means that our definitions in <sane-ctype.h> will be\noverwritten if we allow system-supplied <ctype.h> included, and this\nis an obvious workaround, likely to remain correct as long as their\n<ctype.h> is not so broken to allow multiple inclusion.\n\nFor those who are reading from the sidelines, here is the patch in\ninline form.\n\n--- >8 ---\nSubject: [PATCH] sane-ctype: fix compiler error on Amazon Linux 2\nFrom: Patrick Steinhardt <ps@pks.im>\n\nCompiling Git fails on Amazon Linux 2 when using GCC 7.3.1 with the\nfollowing compiler error:\n\n    In file included from compat/posix.h:449:0,\n                     from git-compat-util.h:26,\n                     from daemon.c:3:\n    compat/../sane-ctype.h:29:60: error: expected expression before ']' token\n     #define sane_istest(x,mask) ((sane_ctype[(unsigned char)(x)] & (mask)) != 0)\n                                                                ^\n    compat/../sane-ctype.h:29:72: error: expected ')' before '!=' token\n     #define sane_istest(x,mask) ((sane_ctype[(unsigned char)(x)] & (mask)) != 0)\n                                                                            ^\n    compat/../sane-ctype.h:29:60: error: expected expression before ']' token\n     #define sane_istest(x,mask) ((sane_ctype[(unsigned char)(x)] & (mask)) != 0)\n                                                                ^\n    ... lots of similar lines ...\n\n    compat/../sane-ctype.h:45:50: error: expected declaration specifiers or '...' before numeric constant\n     #define toupper(x) sane_case((unsigned char)(x), 0)\n                                                      ^\n    /usr/include/ctype.h:142:12: error: expected identifier or '(' before 'int'\n     extern int isascii (int __c) __THROW;\n                ^\n    compat/../sane-ctype.h:30:26: error: expected ')' before '&' token\n     #define isascii(x) (((x) & ~0x7f) == 0)\n                              ^\n    compat/../sane-ctype.h:30:35: error: expected ')' before '==' token\n     #define isascii(x) (((x) & ~0x7f) == 0)\n                                       ^\n    In file included from /usr/include/features.h:423:0,\n                     from /usr/include/unistd.h:25,\n                     from compat/posix.h:90,\n                     from git-compat-util.h:26,\n                     from daemon.c:3:\n    compat/../sane-ctype.h:44:30: error: expected declaration specifiers or '...' before '(' token\n     #define tolower(x) sane_case((unsigned char)(x), 0x20)\n                                  ^\n    compat/../sane-ctype.h:44:50: error: expected declaration specifiers or '...' before numeric constant\n     #define tolower(x) sane_case((unsigned char)(x), 0x20)\n                                                      ^\n    compat/../sane-ctype.h:45:30: error: expected declaration specifiers or '...' before '(' token\n     #define toupper(x) sane_case((unsigned char)(x), 0)\n                                  ^\n    compat/../sane-ctype.h:45:50: error: expected declaration specifiers or '...' before numeric constant\n     #define toupper(x) sane_case((unsigned char)(x), 0)\n                                                      ^\n\nThis error bisect back to 75a044f748 (git-compat-util.h: split out\nPOSIX-emulating bits, 2025-02-18), where lots of bits got split out of\n\"git-compat-util.h\" into a new \"compat/posix.h\" header.\n\nThe compiler error isn't immediately obvious, doubly so because the\nactual errors are ~3x as long as the above snippet. But what happens\nhere is that we transitively include <ctype.h> after we have included\nour own \"sane-ctype.h\" header. Consequently, the function declarations\nthat exist in <ctype.h> for isascii(3p) et al will be mangled by our\nmacros of the same type. The result is of course completely broken.\n\nIt's unclear why this issue only happens on Amazon Linux 2. My guess is\nthat it's either specific to the compiler version or specific to the\nglibc version. We don't explicitly include <ctypes.h> anywhere, but it's\nbeing transitively included. So chances are that later versions of the\ntoolchain reorganized their headers so that <ctypes.h> is not included\ntransitively anymore.\n\nFix the issue by explicitly including <ctype.h> in \"sane-ctype.h\". This\nensures that the header guards will be activated and that any subsequent\ninclude of the same header will become a no-op. With this we can then\nsafely override the function declarations with our own macros.\n\nReported-by: Stan Hu <stanhu@gmail.com>\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n sane-ctype.h | 9 +++++++++\n 1 file changed, 9 insertions(+)\n\ndiff --git a/sane-ctype.h b/sane-ctype.h\nindex cbea1b299b7..4f476c43816 100644\n--- a/sane-ctype.h\n+++ b/sane-ctype.h\n@@ -1,6 +1,15 @@\n #ifndef SANE_CTYPE_H\n #define SANE_CTYPE_H\n \n+/*\n+ * Explicitly include <ctype.h> so that its header guards kick in from here on.\n+ * This ensures that the file won't get included after \"sane-ctype.h\", as that\n+ * would otherwise lead to a compiler error because the function declarations\n+ * for `int isascii(int c)` et al would be mangled by our macros with the same\n+ * name.\n+ */\n+#include <ctype.h>\n+\n /* Sane ctype - no locale, and works with signed chars */\n #undef isascii\n #undef isspace\n"},{"id":"521808","messageId":"aHDDnKx9sK1ctzIR@pks.im","threadId":"63778","inReplyTo":"xmqqtt3j69r8.fsf@gitster.g","subject":"Re: [PATCH RESEND] sane-ctype: fix compiler error on Amazon Linux 2","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2025-07-11T07:56:12Z","receivedAt":"2025-07-11T07:56:19Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Thu, Jul 10, 2025 at 02:01:15PM -0700, Junio C Hamano wrote:\n> Patrick Steinhardt <ps@pks.im> writes:\n> \n> >> > This error bisect back to 75a044f748 (git-compat-util.h: split out\n> >> > POSIX-emulating bits, 2025-02-18), where lots of bits got split out of\n> >> > \"git-compat-util.h\" into a new \"compat/posix.h\" header.\n> \n> So there was a subtle change in the inclusion order or something,\n> i.e. we used to include <sane-ctype.h> a lot earlier as part of the\n> <git-compat-util.h> that tightly controls inclusion order exactly to\n> avoid this kind of problems, but that has eroded recently?\n> \n> In any case, it means that our definitions in <sane-ctype.h> will be\n> overwritten if we allow system-supplied <ctype.h> included, and this\n> is an obvious workaround, likely to remain correct as long as their\n> <ctype.h> is not so broken to allow multiple inclusion.\n\nYup, exactly. Toon figured out that this is actually neither glibc nor\nGCC that causes this -- it's OpenSSL that transitively pulls in\n<ctype.h>. Later versions of OpenSSL seem to not do that anymore.\n\nI can reroll and update the commit message, but am a bit hesitant given\nthat I wasn't able to send out this mail in the first place due to\nwhatever reason :/\n\nPatrick\n"},{"id":"521822","messageId":"xmqqtt3i3gpu.fsf@gitster.g","threadId":"63778","inReplyTo":"aHDDnKx9sK1ctzIR@pks.im","subject":"Re: [PATCH RESEND] sane-ctype: fix compiler error on Amazon Linux 2","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2025-07-11T15:11:25Z","receivedAt":"2025-07-11T15:11:27Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Patrick Steinhardt <ps@pks.im> writes:\n\n> On Thu, Jul 10, 2025 at 02:01:15PM -0700, Junio C Hamano wrote:\n>> Patrick Steinhardt <ps@pks.im> writes:\n>> \n>> >> > This error bisect back to 75a044f748 (git-compat-util.h: split out\n>> >> > POSIX-emulating bits, 2025-02-18), where lots of bits got split out of\n>> >> > \"git-compat-util.h\" into a new \"compat/posix.h\" header.\n>> \n>> So there was a subtle change in the inclusion order or something,\n>> i.e. we used to include <sane-ctype.h> a lot earlier as part of the\n>> <git-compat-util.h> that tightly controls inclusion order exactly to\n>> avoid this kind of problems, but that has eroded recently?\n>> \n>> In any case, it means that our definitions in <sane-ctype.h> will be\n>> overwritten if we allow system-supplied <ctype.h> included, and this\n>> is an obvious workaround, likely to remain correct as long as their\n>> <ctype.h> is not so broken to allow multiple inclusion.\n>\n> Yup, exactly. Toon figured out that this is actually neither glibc nor\n> GCC that causes this -- it's OpenSSL that transitively pulls in\n> <ctype.h>. Later versions of OpenSSL seem to not do that anymore.\n>\n> I can reroll and update the commit message, but am a bit hesitant given\n> that I wasn't able to send out this mail in the first place due to\n> whatever reason :/\n\nI did not see much need to update the proposed log message; I was\nmerely trying to make sure I understand what motivation and\nassumption are behind the change.\n\nIt does make me curious what in your original message got it\ntruncated.  If you received the message you are responding to in\nfull, that means there is not something funky in the diff output\n;-), but then I do not know what it is in your original message,\neither.\n"}]}