fix(demo): sysmalloc_int_free emits a -Wformat warning
Summary
The Constants: block in glibc_2.39/sysmalloc_int_free.c passes MALLOC_ALIGN to printf with %lx at line 55. MALLOC_ALIGN expands to the unsuffixed hexadecimal integer constant 0x10, whose type is int, while %lx requires an unsigned long. GCC therefore reports a -Wformat type mismatch; treating format warnings as errors prevents the demonstration from building.
The same source file is copied unchanged into glibc_2.40, glibc_2.41, glibc_2.42, and glibc_2.43, so all five version directories contain the same mismatch at line 55.
Root-cause classification: compile-time variadic format/argument type mismatch in duplicated demonstration code.
Steps to reproduce
At revision 02da6aa26a44e5af2a67057876d7c6669a207f56, on a Linux host with glibc development headers:
cc -std=c99 -Wformat -Wno-unused-result -Wno-free-nonheap-object \
glibc_2.39/sysmalloc_int_free.c -o sif-test -ldlTo make the red/green result explicit, compile with the corresponding warning promoted to an error:
cc -std=c99 -Werror=format -Wno-unused-result -Wno-free-nonheap-object \
glibc_2.39/sysmalloc_int_free.c -o sif-test -ldlRepeat either command with glibc_2.40, glibc_2.41, glibc_2.42, or glibc_2.43; each directory contains the identical call site.
Expected behavior
sysmalloc_int_free.c should compile without a format/argument type diagnostic under -Wformat, including when that diagnostic is promoted with -Werror=format. The malloc align line should continue to print 0x10.
Actual behavior
GCC diagnoses the call at line 55 because %lx expects unsigned long, but argument 2 has type int:
glibc_2.39/sysmalloc_int_free.c:55: warning: format '%lx' expects argument of type 'long unsigned int', but argument 2 has type 'int' [-Wformat=]With -Werror=format, the same diagnostic stops the build.
Affected area
glibc_2.39/sysmalloc_int_free.c:55glibc_2.40/sysmalloc_int_free.c:55glibc_2.41/sysmalloc_int_free.c:55glibc_2.42/sysmalloc_int_free.c:55glibc_2.43/sysmalloc_int_free.c:55
All five files are byte-identical at the pinned revision. No additional glibc_2.4X directory contains sysmalloc_int_free.c at that revision.
Runtime or environment
- Source revision:
02da6aa26a44e5af2a67057876d7c6669a207f56 - Language mode: C99
- Diagnostic: GCC
-Wformat(also reproduced by Clang's equivalent format checking) - Build prerequisite: a Linux/glibc environment that provides
<malloc.h>
Evidence
The relevant definitions and call are:
#define MALLOC_ALIGN 0x10
printf("malloc align \t\t= 0x%lx\n", MALLOC_ALIGN);The unsuffixed 0x10 is representable as int, so MALLOC_ALIGN has type int. The l length modifier in %lx requires the corresponding variadic argument to have type unsigned long. GCC 14 documents that -Wformat checks printf arguments for types appropriate to their format conversions: GCC 14.3 warning options.
The project build does not suppress this diagnostic. Makefile:23 defines:
CFLAGS += -std=c99 -g -Wno-unused-result -Wno-free-nonheap-objectMakefile:57 passes those flags directly to $(CC), and -Wno-format is not present anywhere in the repository. Consequently, a caller or toolchain configuration that adds -Wformat exposes the warning, while one that adds -Werror=format turns it into a build error.
Impact
The demonstration normally appears to print the intended value on common 64-bit ABIs, but the variadic argument type does not match the conversion specification. The immediate impact is noisy strict builds and a reproducible build failure under -Werror=format; the mismatch also leaves the call's behavior outside the format function's type contract. Severity is low, and the output is not expected to change after the fix.
The red/green closure signal is: the affected source copies fail to compile with -Werror=format before the patch and compile without that diagnostic after it, while continuing to print malloc align = 0x10.
Additional context
A minimal patch is to make the argument type agree with the existing format string in each affected copy:
- printf("malloc align \t\t= 0x%lx\n", MALLOC_ALIGN);
+ printf("malloc align \t\t= 0x%lx\n", (unsigned long)MALLOC_ALIGN);Maintainer checklist:
- Apply the cast to
glibc_2.39/sysmalloc_int_free.cand the identical copies inglibc_2.40throughglibc_2.43. - Compile each affected file with
-Werror=formatand confirm line 55 no longer fails. - Run the demonstrations on a compatible glibc host and confirm the
malloc alignoutput remains0x10. - Keep the existing
Makefile:23warning policy unchanged; no warning-suppression flag is needed for this fix.
Verifier notes
- The exact compile command was attempted on a non-glibc macOS host and stopped at
#include <malloc.h>before format checking, as expected. A minimized translation unit containing the same macro andprintfblock reproduced the line-55 warning under Clang, while the pinned source expressions and GCC 14's documented format rules establish the GCC diagnosis. - The original draft attributed the warning to
CHUNK_HDR_SZand also listed the expressions at lines 59 and 60. That scope is incorrect for the repository's 64-bit targets:CHUNK_HDR_SZexpands throughsizeof(size_t)and issize_t-typed, and the expressions derived from it remainsize_t-typed. The verified issue is therefore narrowed to theint-typedMALLOC_ALIGNargument at line 55. - The original draft's line number for the
CHUNK_HDR_SZcall was also off by one at the pinned revision: that call is at line 54; the confirmedMALLOC_ALIGNmismatch is at line 55. glibc_2.39/sysmalloc_int_free.cand the copies inglibc_2.40,glibc_2.41,glibc_2.42, andglibc_2.43have the same SHA-256 (76b6f23373c715588a715ededc66ac91cae4ebe923b3b1e74dd970028fa89fd3), confirming the per-version scope.
Source: shellphish/how2heap