From 667a9dbcb448738795bc9f51429160d8aed94b5c Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Wed, 28 Oct 2026 08:55:50 +0100 Subject: [PATCH v2 2/2] squash! Add compiler option -fstrict-flex-arrays=1 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. Discussion: https://www.postgresql.org/message-id/flat/c79da9e1-965d-4530-9e3e-84b8bde134ec%40eisentraut.org --- src/include/c.h | 19 +++++++++++++++++++ src/include/tsearch/ts_type.h | 2 +- src/tools/pgindent/pgindent | 1 + 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/include/c.h b/src/include/c.h index b285755e8c4..944c851b3c3 100644 --- a/src/include/c.h +++ b/src/include/c.h @@ -319,6 +319,25 @@ extern "C++" #define pg_attribute_returns_nonnull #endif +/* + * pg_attribute_strict_flex_array(N) overrides -fstrict-flex-arrays=N for a + * particular struct field. It can be used for example to annotate genuine + * trailing one-element array fields, which would under -fstrict-flex-arrays=1 + * otherwise be considered flexible array members and be excluded from bounds + * checking. Use pg_attribute_strict_flex_array(3) for such a case. + * + * Note that it is possible that the command-line option is supported but not + * the attribute. To stay on the safe side, the attribute should not set a + * lower level than the global setting given by the command-line option. + * + * https://gcc.gnu.org/onlinedocs/gcc/Common-Attributes.html#index-strict_005fflex_005farray + */ +#if __has_attribute (strict_flex_array) +#define pg_attribute_strict_flex_array(N) __attribute__((strict_flex_array(N))) +#else +#define pg_attribute_strict_flex_array(N) +#endif + /* * pg_attribute_target allows specifying different target options that the * function should be compiled with (e.g., for using special CPU instructions). diff --git a/src/include/tsearch/ts_type.h b/src/include/tsearch/ts_type.h index 345a2dab930..fdec91fdf13 100644 --- a/src/include/tsearch/ts_type.h +++ b/src/include/tsearch/ts_type.h @@ -76,7 +76,7 @@ typedef struct typedef struct { uint16 npos; - WordEntryPos pos[1]; + pg_attribute_strict_flex_array(3) WordEntryPos pos[1]; } WordEntryPosVector1; #define MAXNUMPOS (256) /* semi-arbitrary limit on npos */ diff --git a/src/tools/pgindent/pgindent b/src/tools/pgindent/pgindent index fa2041dc34b..f75c006bbff 100755 --- a/src/tools/pgindent/pgindent +++ b/src/tools/pgindent/pgindent @@ -253,6 +253,7 @@ sub write_source my @declaration_attributes = qw( alignas pg_attribute_counted_by + pg_attribute_strict_flex_array ); # Text of each declaration attribute, stashed by pre_indent() and restored -- 2.56.0