The counted_by[0] compiler attribute is fairly new. It was added in GCC 
15 and Clang 18. It has been used fairly extensively in the Linux 
kernel[0].

To summarize the benefits of the attribute:

- Runtime bounds checking with -DFORTIFY_SOURCE=3 and -fsanitize-bounds
- Accurate reporting of __builtin_dynamic_object_size()

While we don't use __builtin_dynamic_object_size(), I think the runtime 
bounds checking improvements are easily worth the little bit of effort 
to add the attribute in various locations and review the code. I think 
it will improve things for buildfarm animals using ASan due to expanded 
coverage.

Adding this attribute to the codebase was previously proposed back in 
2024[1], but the thread never got any traction. I figured that I would 
try again, but bring some patches this time. I figured that I would 
start small, and then after people agree that it has value, I can look 
into adding the attribute in many more places.

[0]: 
https://gcc.gnu.org/onlinedocs/gcc/Common-Attributes.html#index-counted_005fby
[1]: 
https://people.kernel.org/gustavoars/how-to-use-the-new-counted_by-attribute-in-c-and-linux
[2]: 
https://www.postgresql.org/message-id/me3p282mb3166210cde36bd485b703bf6b6...@me3p282mb3166.ausp282.prod.outlook.com

-- 
Tristan Partin
PostgreSQL Contributors Team
AWS (https://aws.amazon.com)
From 27cc7c57bb211b74bbcf0d2f2bb6618a759b75dc Mon Sep 17 00:00:00 2001
From: Tristan Partin <[email protected]>
Date: Wed, 29 Jul 2026 19:38:39 +0000
Subject: [PATCH v1 1/2] Add pg_attribute_counted_by()

The counted_by attribute allows specifying that an array member (pointer
or flexible array) of a struct is "counted by" another member of the
same struct. Not only does this attribute make arrays a little more
self-documenting, but it is also a hint to the compiler that can improve
detection of object size information and provide better results in
compile time diagnostics and runtime features like the array bound
sanitizer.

Signed-off-by: Tristan Partin <[email protected]>
---
 src/include/c.h | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/src/include/c.h b/src/include/c.h
index 20cfbac54e7..e83c1e391a7 100644
--- a/src/include/c.h
+++ b/src/include/c.h
@@ -297,6 +297,18 @@ extern "C++"
 #define pg_attribute_target(...)
 #endif
 
+/*
+ * pg_attribute_counted_by allows specifying that an array is "counted by"
+ * another struct member. This provides the compiler to improve detection of
+ * object size information and provide better results in compile time
+ * diagnostics and runtime features like the array bound sanitizer.
+ */
+#if __has_attribute (counted_by)
+#define pg_attribute_counted_by(...) __attribute__((counted_by(__VA_ARGS__)))
+#else
+#define pg_attribute_counted_by(...)
+#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
-- 
Tristan Partin
https://tristan.partin.io

From dec7443048033cc620b9c5a4f84e4d43e90f0f18 Mon Sep 17 00:00:00 2001
From: Tristan Partin <[email protected]>
Date: Wed, 29 Jul 2026 21:12:10 +0000
Subject: [PATCH v1 2/2] Make use of counted_by attribute

These are two trivial changes that show how pg_attribute_counted_by can
be used throughout the codebase.

Signed-off-by: Tristan Partin <[email protected]>
---
 src/backend/storage/file/buffile.c | 2 +-
 src/backend/utils/sort/tuplesort.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/backend/storage/file/buffile.c b/src/backend/storage/file/buffile.c
index 5c59913646b..649d21420a2 100644
--- a/src/backend/storage/file/buffile.c
+++ b/src/backend/storage/file/buffile.c
@@ -72,7 +72,7 @@ struct BufFile
 {
 	int			numFiles;		/* number of physical files in set */
 	/* all files except the last have length exactly MAX_PHYSICAL_FILESIZE */
-	File	   *files;			/* palloc'd array with numFiles entries */
+	File	   *files pg_attribute_counted_by(numFiles);	/* palloc'd array with numFiles entries */
 
 	bool		isInterXact;	/* keep open over transactions? */
 	bool		dirty;			/* does buffer need to be written? */
diff --git a/src/backend/utils/sort/tuplesort.c b/src/backend/utils/sort/tuplesort.c
index c0e7527b9ca..49868071c66 100644
--- a/src/backend/utils/sort/tuplesort.c
+++ b/src/backend/utils/sort/tuplesort.c
@@ -364,7 +364,7 @@ struct Sharedsort
 	 * Tapes array used by workers to report back information needed by the
 	 * leader to concatenate all worker tapes into one for merging
 	 */
-	TapeShare	tapes[FLEXIBLE_ARRAY_MEMBER];
+	TapeShare	tapes[FLEXIBLE_ARRAY_MEMBER] pg_attribute_counted_by(nTapes);
 };
 
 /*
-- 
Tristan Partin
https://tristan.partin.io

Reply via email to