diff --git a/src/backend/utils/adt/jsonfuncs.c b/src/backend/utils/adt/jsonfuncs.c index bc7b556e22e..64c85e9ddd1 100644 --- a/src/backend/utils/adt/jsonfuncs.c +++ b/src/backend/utils/adt/jsonfuncs.c @@ -233,7 +233,7 @@ struct RecordIOData Oid record_type; int32 record_typmod; int ncolumns; - ColumnIOData columns[FLEXIBLE_ARRAY_MEMBER]; + ColumnIOData columns[FLEXIBLE_ARRAY_MEMBER] pg_attribute_counted_by(ncolumns); }; /* per-query cache for populate_record_worker and populate_recordset_worker */ diff --git a/src/include/c.h b/src/include/c.h index 3b75f0b8610..57d891e52a7 100644 --- a/src/include/c.h +++ b/src/include/c.h @@ -297,6 +297,30 @@ extern "C++" #define pg_attribute_target(...) #endif +/* + * pg_attribute_counted_by specifies that a flexible array member is "counted + * by" another struct member. This allows the compiler to improve detection + * of object size information and to provide better results in compile-time + * diagnostics and run-time features, such as the array bounds sanitizer. + * + * Using this annotation comes with additional responsibilities: + * + * - The count must be assigned before the first reference to the array. + * - The array must have at least count elements available at all times, + * including after either member is updated. + * + * The attribute is ignored in C++ due to lack of compiler support. + */ +#ifndef __cplusplus +#if __has_attribute (counted_by) +#define pg_attribute_counted_by(count) __attribute__((counted_by(count))) +#else +#define pg_attribute_counted_by(count) +#endif +#else +#define pg_attribute_counted_by(count) +#endif + /* * Append PG_USED_FOR_ASSERTS_ONLY to definitions of variables that are only * used in assert-enabled builds, to avoid compiler warnings about unused