From: Patrick Steinhardt <ps@pks.im>
To: git@vger.kernel.org
Cc: Stan Hu <stanhu@gmail.com>,
Konstantin Ryabitsev <konstantin@linuxfoundation.org>
Subject: Re: [PATCH RESEND] sane-ctype: fix compiler error on Amazon Linux 2
Date: Thu, 10 Jul 2025 11:26:10 +0200 [thread overview]
Message-ID: <aG-HMnO11lCYgPiY@pks.im> (raw)
In-Reply-To: <aG-EfIfyXxmS_x22@pks.im>
[-- Attachment #1: Type: text/plain, Size: 4394 bytes --]
On Thu, Jul 10, 2025 at 11:14:36AM +0200, Patrick Steinhardt wrote:
> On Thu, Jul 10, 2025 at 11:12:40AM +0200, Patrick Steinhardt wrote:
> > 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 75a044f748 (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
>
> Hrmpf, what's going on here? Both this email and the first one at [1]
> are getting truncated... I'll debug.
I've tested with multiple other recipients, works alright there. No
truncation, the mail comes through as expected. I'm a bit clueless right
now. Konstantin, do you have any idea why this might have happened?
Meanwhile, I'll include the patch as an attachment.
Patrick
[-- Attachment #2: 0001-sane-ctype-fix-compiler-error-on-Amazon-Linux-2.patch --]
[-- Type: text/plain, Size: 5063 bytes --]
From fabacc9bc7ef7d462d1c7198d5edc18c76b82270 Mon Sep 17 00:00:00 2001
Message-ID: <fabacc9bc7ef7d462d1c7198d5edc18c76b82270.1752139420.git.ps@pks.im>
From: Patrick Steinhardt <ps@pks.im>
Date: Thu, 10 Jul 2025 08:46:27 +0200
Subject: [PATCH] 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 75a044f748 (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 <stanhu@gmail.com>
Signed-off-by: Patrick Steinhardt <ps@pks.im>
---
sane-ctype.h | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/sane-ctype.h b/sane-ctype.h
index cbea1b299b7..4f476c43816 100644
--- a/sane-ctype.h
+++ b/sane-ctype.h
@@ -1,6 +1,15 @@
#ifndef SANE_CTYPE_H
#define SANE_CTYPE_H
+/*
+ * Explicitly include <ctype.h> so that its header guards kick in from here on.
+ * This ensures that the file won't get included after "sane-ctype.h", as that
+ * would otherwise lead to a compiler error because the function declarations
+ * for `int isascii(int c)` et al would be mangled by our macros with the same
+ * name.
+ */
+#include <ctype.h>
+
/* Sane ctype - no locale, and works with signed chars */
#undef isascii
#undef isspace
--
2.50.1.337.g200b4b24a8.dirty
next prev parent reply other threads:[~2025-07-10 9:26 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-07-10 9:12 [PATCH RESEND] sane-ctype: fix compiler error on Amazon Linux 2 Patrick Steinhardt
2025-07-10 9:14 ` Patrick Steinhardt
2025-07-10 9:26 ` Patrick Steinhardt [this message]
2025-07-10 10:17 ` Toon Claes
2025-07-10 21:01 ` Junio C Hamano
2025-07-11 7:56 ` Patrick Steinhardt
2025-07-11 15:11 ` Junio C Hamano
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=aG-HMnO11lCYgPiY@pks.im \
--to=ps@pks.im \
--cc=git@vger.kernel.org \
--cc=konstantin@linuxfoundation.org \
--cc=stanhu@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).