pgsql: Add compiler option -fstrict-flex-arrays=1

From: Peter Eisentraut <peter(at)eisentraut(dot)org>
To: pgsql-committers(at)lists(dot)postgresql(dot)org
Subject: pgsql: Add compiler option -fstrict-flex-arrays=1
Date: 2026-11-04 09:07:50
Message-ID: E1xOWyF-000000009BO-0Q2k@gemulon.postgresql.org
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-committers

Add compiler option -fstrict-flex-arrays=1

Currently, every trailing array regardless of its declared bound is
exempt from -Warray-bounds, __builtin_object_size/_FORTIFY_SOURCE, and
-fsanitize=bounds. -fstrict-flex-arrays=1 says that only arrays
declared with bounds [], [0], or [1] can be flexible array
members (which are then mostly exempt from array bounds checking); for
all other arrays, the declared size is taken as is for bounds
checking, which is what we want.

This applies to a large number of structs in the tree, for example

- struct pg_hmac_ctx
- fe_scram_state
- struct XidCache
- struct RelPathStr
...

which can now be checked properly.

Ideally, we'd want to use the maximum level -fstrict-flex-arrays=3,
which would also disqualify flexible array members declared with
bounds [0] or [1]. But we do need the [1] variant in a few cases
because standard C does not allow flexible array members as the only
element in a struct. Affected are:

- struct RevmapContents
- struct ReplicationSlotCtlData
- union pgresult_data

Also:

- struct sqlda_struct (bound by external API specification)

Turning on -fstrict-flex-arrays=3 for these would conjure undefined
behavior.

One piece of code needs to be adjusted: JsonValueList has an array
declared as [2] (via BASE_JVL_ITEMS) but addresses it as a
flexible-length array in some circumstances. Change this to an
anonymous union with one branch having the original size [2], to keep
local variables sized the same as before, and one branch of size [1],
which effectively makes this a flexible-array member under
-fstrict-flex-arrays=1. We can't make it a fully flexible-array
member [], because JsonValueList is also used for a field in the
middle of JsonTablePlanState, which is not allowed in standard C.

There is one structure with a genuine trailing one-element array:

- WordEntryPosVector1

By staying with -fstrict-flex-arrays=1 we would miss out on bounds
checking on that one.

Also provide an attribute macro pg_attribute_strict_flex_array that
allows overriding the strict flex array level for a particular struct.
Use that to annotate WordEntryPosVector1. Note that clang supports
the command-line option but not the attribute, so we can only use this
to optionally raise the level for some structs, but we can't do the
opposite of having a higher global level and lower it for some
exceptions.

Reviewed-by: Tristan Partin <tristan(at)partin(dot)io>
Reviewed-by: Greg Burd <greg(at)burd(dot)me>
Discussion: https://www.postgresql.org/message-id/flat/c79da9e1-965d-4530-9e3e-84b8bde134ec%40eisentraut.org

Branch
------
master

Details
-------
https://git.postgresql.org/pg/commitdiff/a625e153b7d2f0e1c81955d13f2fc8de472bc082

Modified Files
--------------
configure | 92 +++++++++++++++++++++++++++++++++++
configure.ac | 3 ++
meson.build | 2 +
src/backend/utils/adt/jsonpath_exec.c | 16 +++++-
src/include/c.h | 19 ++++++++
src/include/tsearch/ts_type.h | 2 +-
src/tools/pgindent/pgindent | 1 +
7 files changed, 133 insertions(+), 2 deletions(-)

Browse pgsql-committers by date

  From Date Subject
Next Message Etsuro Fujita 2026-11-04 09:34:19 pgsql: Fix comment in ExecAppendAsyncReset.
Previous Message Richard Guo 2026-11-04 07:25:15 pgsql: Fix NOT IN to anti-join conversion with coerced sub-select outpu