From a75b8322239502a085664b472f7f7340dca4a1a7 Mon Sep 17 00:00:00 2001
From: Tristan Partin <tristan@partin.io>
Date: Wed, 23 Sep 2026 01:44:16 +0000
Subject: [PATCH v2 1/8] Add pg_attribute_counted_by()

The counted_by attribute allows specifying that an array member of
a struct is "counted by" another member of the same struct. The
attribute makes arrays a little more self-documenting, but it is also
a hint to the compiler such that it can improve detection of object size
information and provide better results in compile-time diagnostics and
runtime features, like the array bounds sanitizer.

Both GCC and clang warn when the attribute is used in C++, where it is
ignored, so define it away there.

Note that in its current form, it is best used for flexible array
members only. Pointer array support may come later on.

Author: Tristan Partin <tristan@partin.io>
Signed-off-by: Tristan Partin <tristan@partin.io>
---
 src/backend/nodes/gen_node_support.pl |  2 ++
 src/include/c.h                       | 24 ++++++++++++++++++++++++
 2 files changed, 26 insertions(+)

diff --git a/src/backend/nodes/gen_node_support.pl b/src/backend/nodes/gen_node_support.pl
index 0b766272018..53866dc34d4 100644
--- a/src/backend/nodes/gen_node_support.pl
+++ b/src/backend/nodes/gen_node_support.pl
@@ -226,6 +226,8 @@ sub elem
 		$lineno++;
 		chomp $line;
 		$line =~ s/\s*$//;
+		# counted_by() annotations are not interesting for node support
+		$line =~ s/\s*pg_attribute_counted_by\(\w+\)//;
 		next if $line eq '';
 		next if $line =~ /^#(define|ifdef|endif)/;
 
diff --git a/src/include/c.h b/src/include/c.h
index 20cfbac54e7..6505a0d00ff 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 allows specifying that an array is "counted by"
+ * another struct member. This allows the compiler to improve detection of
+ * object size information provide better results in compile-time diagnostics
+ * and runtime features, like the array bound 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
-- 
Tristan Partin
https://tristan.partin.io

