From 6eeeb7c3d17756e9916b4c0aeb2c993f9c3c013a Mon Sep 17 00:00:00 2001 From: Zsolt Parragi Date: Tue, 17 Mar 2026 16:19:39 +0000 Subject: [PATCH 2/4] Add PG_NO_PADDING, PG_REQUIRE_NO_PADDING, and padding helper macros Introduce compiler annotation macros in c.h for enforcing struct padding constraints at build time via the pg-tidy clang-tidy plugin: - PG_NO_PADDING: marks a struct as requiring no implicit padding - PG_REQUIRE_NO_PADDING: marks a function parameter as requiring that the argument type be annotated with PG_NO_PADDING - pg_padding_1/2/4: helper macros to declare explicit padding fields using appropriately sized integer types Annotate the data parameter of XLogRegisterData() with PG_REQUIRE_NO_PADDING to enforce that all data written to WAL records contains no uninitialized padding bytes. --- src/include/access/xloginsert.h | 2 +- src/include/c.h | 29 +++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src/include/access/xloginsert.h b/src/include/access/xloginsert.h index 16ebc76e743..527d40c7531 100644 --- a/src/include/access/xloginsert.h +++ b/src/include/access/xloginsert.h @@ -46,7 +46,7 @@ extern void XLogSetRecordFlags(uint8 flags); extern XLogRecPtr XLogInsert(RmgrId rmid, uint8 info); extern XLogRecPtr XLogSimpleInsertInt64(RmgrId rmid, uint8 info, int64 value); extern void XLogEnsureRecordSpace(int max_block_id, int ndatas); -extern void XLogRegisterData(const void *data, uint32 len); +extern void XLogRegisterData(const void *data PG_REQUIRE_NO_PADDING, uint32 len); extern void XLogRegisterBuffer(uint8 block_id, Buffer buffer, uint8 flags); extern void XLogRegisterBlock(uint8 block_id, RelFileLocator *rlocator, ForkNumber forknum, BlockNumber blknum, const PageData *page, diff --git a/src/include/c.h b/src/include/c.h index fb0ea1bc680..9601455b7fb 100644 --- a/src/include/c.h +++ b/src/include/c.h @@ -274,6 +274,35 @@ */ #endif +/* + * PG_NO_PADDING marks a struct definition as requiring no implicit padding. + * When pg-tidy clang-tidy checks are enabled, structs with this annotation + * will be verified at build time to contain no compiler-inserted padding. + * + * PG_REQUIRE_NO_PADDING marks a function parameter as requiring that the + * argument type be annotated with PG_NO_PADDING. + * + * These use compiler annotations that are checked by the pg-tidy clang-tidy + * plugin. On compilers that don't support annotations, they expand to + * nothing. + */ +#ifdef __clang__ +#define PG_NO_PADDING __attribute__((annotate("pg_no_padding"))) +#define PG_REQUIRE_NO_PADDING __attribute__((annotate("pg_requires_no_padding"))) +#else +#define PG_NO_PADDING +#define PG_REQUIRE_NO_PADDING +#endif + +/* + * Macros for explicit struct padding. Use these to replace implicit + * compiler-inserted padding in structs marked PG_NO_PADDING. Each macro + * declares a field of the appropriately sized integer type. + */ +#define pg_padding_1(name) uint8 name +#define pg_padding_2(name) uint16 name +#define pg_padding_4(name) uint32 name + /* * Use "pg_attribute_always_inline" in place of "inline" for functions that * we wish to force inlining of, even when the compiler's heuristics would -- 2.43.0