The counted_by attribute of clang >= 19 and gcc >= 16.x (probably, x >= 2)
helps the UBSAN do bounds checking on some pointer references. So, it is
useful for detecting memory errors before a release (and cheaper to use
than valgrind).

There are two drawbacks, though:
  - In code that adds an element to an array, the 'count' must be
    incremented before the code writes the new element to memory.
  - The 'count' field must occur before the array or pointer field.
    This is not a requirement in gcc, but is one in clang. See
    
<https://discourse.llvm.org/t/rfc-forward-referencing-a-struct-member-within-bounds-annotations/85510>

These two drawbacks are small enough that the use of 'counted_by'
appears worthwhile.

These patches adds a counted_by attribute where possible, except in
the regex module.


2026-05-03  Bruno Haible  <[email protected]>

        acl-permissions: Use the counted_by attribute.
        * lib/acl-internal.h (struct permission_context): On Solaris, mark the
        entries field as counted_by count and the ace_entries field as
        counted_by ace_count.

2026-05-03  Bruno Haible  <[email protected]>

        windows-spawn: Use the counted_by attribute.
        * lib/windows-spawn.h (struct inheritable_handles): Mark the ih field as
        counted_by count.

2026-05-03  Bruno Haible  <[email protected]>

        string-desc: Use the counted_by attribute.
        * lib/string-desc.h (struct rw_string_desc_t, struct string_desc_t):
        Mark the _data field as counted_by _nbytes.

2026-05-03  Bruno Haible  <[email protected]>

        ssfmalloc: Use the counted_by attribute.
        * lib/ssfmalloc.h (struct medium_page_header): Mark the gaps field as
        counted_by num_gaps.
        (allocate_medium_block_in_page): Increase pageptr->num_gaps before
        writing into pageptr->gaps.

2026-05-03  Bruno Haible  <[email protected]>

        readtokens: Use the counted_by attribute.
        * lib/readtokens.h (struct tokenbuffer): Mark the buffer field as
        counted_by size.

2026-05-03  Bruno Haible  <[email protected]>

        mbfile: Add comments regarding the counted_by attribute.
        * lib/mbfile.h (struct mbfile_multi): Clarify how many elements of the
        fields buf and pushback are used.

2026-05-03  Bruno Haible  <[email protected]>

        linebuffer: Use the counted_by attribute.
        * lib/linebuffer.h (struct linebuffer): Mark the buffer field as
        counted_by size.

2026-05-03  Bruno Haible  <[email protected]>

        hash: Use the counted_by attribute.
        * lib/hash.c (struct hash_table): Mark the bucket field as counted_by
        n_buckets. Swap these fields (needed for clang, see
        
<https://discourse.llvm.org/t/rfc-forward-referencing-a-struct-member-within-bounds-annotations/85510>).

2026-05-03  Bruno Haible  <[email protected]>

        linkedhash-set: Use the counted_by attribute.
        * lib/gl_linkedhash_set.c (struct gl_set_impl): Mark the table field as
        counted_by table_size. Swap these fields (needed for clang).

2026-05-03  Bruno Haible  <[email protected]>

        hash-set: Use the counted_by attribute.
        * lib/gl_hash_set.c (struct gl_set_impl): Mark the table field as
        counted_by table_size. Swap these fields (needed for clang).

2026-05-03  Bruno Haible  <[email protected]>

        linkedhash-map: Use the counted_by attribute.
        * lib/gl_linkedhash_map.c (struct gl_map_impl): Mark the table field as
        counted_by table_size. Swap these fields (needed for clang).

2026-05-03  Bruno Haible  <[email protected]>

        hash-map: Use the counted_by attribute.
        * lib/gl_hash_map.c (struct gl_map_impl): Mark the table field as
        counted_by table_size. Swap these fields (needed for clang).

2026-05-03  Bruno Haible  <[email protected]>

        linkedhash-list: Use the counted_by attribute.
        * lib/gl_anylinked_list1.h (struct gl_list_impl): Mark the table field
        as counted_by table_size. Swap these fields (needed for clang).

2026-05-03  Bruno Haible  <[email protected]>

        rbtreehash-list: Use the counted_by attribute.
        * lib/gl_anyrbtree_list1.h (struct gl_list_impl): Mark the table field
        as counted_by table_size. Swap these fields (needed for clang).

2026-05-03  Bruno Haible  <[email protected]>

        avltreehash-list: Use the counted_by attribute.
        * lib/gl_anyavltree_list1.h (struct gl_list_impl): Mark the table field
        as counted_by table_size. Swap these fields (needed for clang).

2026-05-03  Bruno Haible  <[email protected]>

        carray-list: Use the counted_by attribute.
        * lib/gl_carray_list.c (struct gl_list_impl): Mark the elements field as
        counted_by allocated. Swap these fields (needed for clang).

2026-05-03  Bruno Haible  <[email protected]>

        array-set: Use the counted_by attribute.
        * lib/gl_array_set.c (struct gl_set_impl): Mark the elements field as
        counted_by count. Swap these fields (needed for clang).
        (gl_array_nx_add): Increase set->count before writing into
        set->elements.

2026-05-03  Bruno Haible  <[email protected]>

        array-oset: Use the counted_by attribute.
        * lib/gl_array_oset.c (struct gl_oset_impl): Mark the elements field as
        counted_by count. Swap these fields (needed for clang).
        (gl_array_nx_add_at): Increase set->count before writing into
        set->elements.

2026-05-03  Bruno Haible  <[email protected]>

        array-omap: Use the counted_by attribute.
        * lib/gl_array_omap.c (struct gl_omap_impl): Mark the pairs field as
        counted_by count. Swap these fields (needed for clang).
        (gl_array_nx_add_at): Increase map->count before writing into
        map->pairs.

2026-05-03  Bruno Haible  <[email protected]>

        array-map: Use the counted_by attribute.
        * lib/gl_array_map.c (struct gl_map_impl): Mark the pairs field as
        counted_by count. Swap these fields (needed for clang).
        (gl_array_nx_getput): Increase map->count before writing into
        map->pairs.

2026-05-03  Bruno Haible  <[email protected]>

        array-list: Use the counted_by attribute.
        * lib/gl_array_list.c (struct gl_list_impl): Mark the elements field as
        counted_by count. Swap these fields (needed for clang).
        (gl_array_nx_add_first, gl_array_nx_add_last, gl_array_nx_add_before,
        gl_array_nx_add_after, gl_array_nx_add_at): Increase list->count before
        writing into list->elements.

2026-05-03  Bruno Haible  <[email protected]>

        exclude: Use the counted_by attribute.
        * lib/exclude.c (struct exclude_pattern): Mark the exclude field as
        counted_by exclude_count. Swap these fields (needed for clang, see
        
<https://discourse.llvm.org/t/rfc-forward-referencing-a-struct-member-within-bounds-annotations/85510>).
        (new_exclude_segment): Update.
        (add_exclude): Increase pat->exclude_count before writing into
        pat->exclude.

2026-05-03  Bruno Haible  <[email protected]>

        dfa: Use the counted_by attribute.
        * lib/dfa.c (struct mb_char_classes): Mark the chars field as counted_by
        nchars. Swap these fields (needed for clang, see
        
<https://discourse.llvm.org/t/rfc-forward-referencing-a-struct-member-within-bounds-annotations/85510>).
        (parse_bracket_exp): Increase dfa->lex.brack.nchars before writing into
        dfa->lex.brack.chars.

2026-05-03  Bruno Haible  <[email protected]>

        argp: Use the counted_by attribute.
        * lib/argp-help.c (struct hol): Mark the entries fields as counted_by
        num_entries. Swap these fields (needed for clang, see
        
<https://discourse.llvm.org/t/rfc-forward-referencing-a-struct-member-within-bounds-annotations/85510>).

>From e63ae1335b5fbdc6c6510e30525abbdbc8a60db0 Mon Sep 17 00:00:00 2001
From: Bruno Haible <[email protected]>
Date: Sun, 3 May 2026 08:51:08 +0200
Subject: [PATCH 01/24] argp: Use the counted_by attribute.

* lib/argp-help.c (struct hol): Mark the entries fields as counted_by
num_entries. Swap these fields (needed for clang, see
<https://discourse.llvm.org/t/rfc-forward-referencing-a-struct-member-within-bounds-annotations/85510>).
---
 ChangeLog       | 7 +++++++
 lib/argp-help.c | 5 +++--
 2 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index af44055e31..84bc54f299 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2026-05-03  Bruno Haible  <[email protected]>
+
+	argp: Use the counted_by attribute.
+	* lib/argp-help.c (struct hol): Mark the entries fields as counted_by
+	num_entries. Swap these fields (needed for clang, see
+	<https://discourse.llvm.org/t/rfc-forward-referencing-a-struct-member-within-bounds-annotations/85510>).
+
 2026-05-03  Bruno Haible  <[email protected]>
 
 	dfa: Remove a redundant forward declaration.
diff --git a/lib/argp-help.c b/lib/argp-help.c
index 8a3e72e79c..d925336775 100644
--- a/lib/argp-help.c
+++ b/lib/argp-help.c
@@ -419,11 +419,12 @@ struct hol_cluster
 /* A list of options for help.  */
 struct hol
 {
-  /* An array of hol_entry's.  */
-  struct hol_entry *entries;
   /* The number of entries in this hol.  If this field is zero, entries and
      short_options are undefined.  */
   unsigned num_entries;
+  /* An array of hol_entry's.  */
+  struct hol_entry *entries
+    _GL_ATTRIBUTE_COUNTED_BY (num_entries);
 
   /* A string containing all short options in this HOL.  Each entry contains
      pointers into this string, so the order can't be messed with blindly.  */
-- 
2.52.0

>From 46e36ea9b1bbfa2fabac09cba113b8751576c535 Mon Sep 17 00:00:00 2001
From: Bruno Haible <[email protected]>
Date: Sun, 3 May 2026 10:52:33 +0200
Subject: [PATCH 03/24] exclude: Use the counted_by attribute.

* lib/exclude.c (struct exclude_pattern): Mark the exclude field as
counted_by exclude_count. Swap these fields (needed for clang, see
<https://discourse.llvm.org/t/rfc-forward-referencing-a-struct-member-within-bounds-annotations/85510>).
(new_exclude_segment): Update.
(add_exclude): Increase pat->exclude_count before writing into
pat->exclude.
---
 ChangeLog     | 10 ++++++++++
 lib/exclude.c | 10 ++++++----
 2 files changed, 16 insertions(+), 4 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index a228019e0a..e3d0de73cf 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2026-05-03  Bruno Haible  <[email protected]>
+
+	exclude: Use the counted_by attribute.
+	* lib/exclude.c (struct exclude_pattern): Mark the exclude field as
+	counted_by exclude_count. Swap these fields (needed for clang, see
+	<https://discourse.llvm.org/t/rfc-forward-referencing-a-struct-member-within-bounds-annotations/85510>).
+	(new_exclude_segment): Update.
+	(add_exclude): Increase pat->exclude_count before writing into
+	pat->exclude.
+
 2026-05-03  Bruno Haible  <[email protected]>
 
 	dfa: Use the counted_by attribute.
diff --git a/lib/exclude.c b/lib/exclude.c
index 8cf4103c11..6a8604ec1b 100644
--- a/lib/exclude.c
+++ b/lib/exclude.c
@@ -89,9 +89,10 @@ struct patopts
 
 struct exclude_pattern
   {
-    struct patopts *exclude;
-    idx_t exclude_alloc;
     idx_t exclude_count;
+    struct patopts *exclude
+      _GL_ATTRIBUTE_COUNTED_BY (exclude_count);
+    idx_t exclude_alloc;
   };
 
 enum exclude_type
@@ -261,7 +262,7 @@ new_exclude_segment (struct exclude *ex, enum exclude_type type, int options)
   switch (type)
     {
     case exclude_pattern:
-      sp->v.pat = (struct exclude_pattern) { NULL, 0, 0 };
+      sp->v.pat = (struct exclude_pattern) { 0, NULL, 0 };
       break;
 
     case exclude_hash:
@@ -519,7 +520,8 @@ add_exclude (struct exclude *ex, char const *pattern, int options)
       if (pat->exclude_count == pat->exclude_alloc)
         pat->exclude = xpalloc (pat->exclude, &pat->exclude_alloc, 1, -1,
                                 sizeof *pat->exclude);
-      struct patopts *patopts = &pat->exclude[pat->exclude_count++];
+      idx_t pat_index = pat->exclude_count++;
+      struct patopts *patopts = &pat->exclude[pat_index];
 
       patopts->options = options;
       if (options & EXCLUDE_REGEX)
-- 
2.52.0

>From 63897e4d37383f84eb4a6e55dd3b6cfd284219cf Mon Sep 17 00:00:00 2001
From: Bruno Haible <[email protected]>
Date: Sun, 3 May 2026 10:40:52 +0200
Subject: [PATCH 02/24] dfa: Use the counted_by attribute.

* lib/dfa.c (struct mb_char_classes): Mark the chars field as counted_by
nchars. Swap these fields (needed for clang, see
<https://discourse.llvm.org/t/rfc-forward-referencing-a-struct-member-within-bounds-annotations/85510>).
(parse_bracket_exp): Increase dfa->lex.brack.nchars before writing into
dfa->lex.brack.chars.
---
 ChangeLog | 9 +++++++++
 lib/dfa.c | 6 ++++--
 2 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 84bc54f299..a228019e0a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2026-05-03  Bruno Haible  <[email protected]>
+
+	dfa: Use the counted_by attribute.
+	* lib/dfa.c (struct mb_char_classes): Mark the chars field as counted_by
+	nchars. Swap these fields (needed for clang, see
+	<https://discourse.llvm.org/t/rfc-forward-referencing-a-struct-member-within-bounds-annotations/85510>).
+	(parse_bracket_exp): Increase dfa->lex.brack.nchars before writing into
+	dfa->lex.brack.chars.
+
 2026-05-03  Bruno Haible  <[email protected]>
 
 	argp: Use the counted_by attribute.
diff --git a/lib/dfa.c b/lib/dfa.c
index 7719e80669..13dae682ed 100644
--- a/lib/dfa.c
+++ b/lib/dfa.c
@@ -385,8 +385,9 @@ struct mb_char_classes
 {
   ptrdiff_t cset;
   bool invert;
-  char32_t *chars;              /* Normal characters.  */
   idx_t nchars;
+  char32_t *chars               /* Normal characters.  */
+    _GL_ATTRIBUTE_COUNTED_BY (nchars);
   idx_t nchars_alloc;
 };
 
@@ -1127,7 +1128,8 @@ parse_bracket_exp (struct dfa *dfa)
                   = maybe_realloc (dfa->lex.brack.chars, dfa->lex.brack.nchars,
                                    &dfa->lex.brack.nchars_alloc, -1,
                                    sizeof *dfa->lex.brack.chars);
-                dfa->lex.brack.chars[dfa->lex.brack.nchars++] = folded[i];
+                idx_t char_index = dfa->lex.brack.nchars++;
+                dfa->lex.brack.chars[char_index] = folded[i];
               }
         }
     }
-- 
2.52.0

>From 5280006ba0a89b15ad40509f97f8ead44a9bf2fd Mon Sep 17 00:00:00 2001
From: Bruno Haible <[email protected]>
Date: Sun, 3 May 2026 11:41:31 +0200
Subject: [PATCH 04/24] array-list: Use the counted_by attribute.

* lib/gl_array_list.c (struct gl_list_impl): Mark the elements field as
counted_by count. Swap these fields (needed for clang).
(gl_array_nx_add_first, gl_array_nx_add_last, gl_array_nx_add_before,
gl_array_nx_add_after, gl_array_nx_add_at): Increase list->count before
writing into list->elements.
---
 ChangeLog           |  9 +++++++++
 lib/gl_array_list.c | 15 ++++++++-------
 2 files changed, 17 insertions(+), 7 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index e3d0de73cf..7bb7e0b36d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2026-05-03  Bruno Haible  <[email protected]>
+
+	array-list: Use the counted_by attribute.
+	* lib/gl_array_list.c (struct gl_list_impl): Mark the elements field as
+	counted_by count. Swap these fields (needed for clang).
+	(gl_array_nx_add_first, gl_array_nx_add_last, gl_array_nx_add_before,
+	gl_array_nx_add_after, gl_array_nx_add_at): Increase list->count before
+	writing into list->elements.
+
 2026-05-03  Bruno Haible  <[email protected]>
 
 	exclude: Use the counted_by attribute.
diff --git a/lib/gl_array_list.c b/lib/gl_array_list.c
index 6e80377008..b9d36c9599 100644
--- a/lib/gl_array_list.c
+++ b/lib/gl_array_list.c
@@ -34,10 +34,11 @@
 struct gl_list_impl
 {
   struct gl_list_impl_base base;
+  size_t count;
   /* An array of ALLOCATED elements, of which the first COUNT are used.
      0 <= COUNT <= ALLOCATED.  */
-  const void **elements;
-  size_t count;
+  const void **elements
+    _GL_ATTRIBUTE_COUNTED_BY (count);
   size_t allocated;
 };
 
@@ -283,10 +284,10 @@ gl_array_nx_add_first (gl_list_t list, const void *elt)
     if (grow (list) < 0)
       return NULL;
   const void **elements = list->elements;
+  list->count = count + 1;
   for (size_t i = count; i > 0; i--)
     elements[i] = elements[i - 1];
   elements[0] = elt;
-  list->count = count + 1;
   return INDEX_TO_NODE (0);
 }
 
@@ -298,8 +299,8 @@ gl_array_nx_add_last (gl_list_t list, const void *elt)
   if (count == list->allocated)
     if (grow (list) < 0)
       return NULL;
-  list->elements[count] = elt;
   list->count = count + 1;
+  list->elements[count] = elt;
   return INDEX_TO_NODE (count);
 }
 
@@ -317,10 +318,10 @@ gl_array_nx_add_before (gl_list_t list, gl_list_node_t node, const void *elt)
     if (grow (list) < 0)
       return NULL;
   const void **elements = list->elements;
+  list->count = count + 1;
   for (size_t i = count; i > position; i--)
     elements[i] = elements[i - 1];
   elements[position] = elt;
-  list->count = count + 1;
   return INDEX_TO_NODE (position);
 }
 
@@ -338,10 +339,10 @@ gl_array_nx_add_after (gl_list_t list, gl_list_node_t node, const void *elt)
     if (grow (list) < 0)
       return NULL;
   const void **elements = list->elements;
+  list->count = count + 1;
   for (size_t i = count; i > position; i--)
     elements[i] = elements[i - 1];
   elements[position] = elt;
-  list->count = count + 1;
   return INDEX_TO_NODE (position);
 }
 
@@ -357,10 +358,10 @@ gl_array_nx_add_at (gl_list_t list, size_t position, const void *elt)
     if (grow (list) < 0)
       return NULL;
   const void **elements = list->elements;
+  list->count = count + 1;
   for (size_t i = count; i > position; i--)
     elements[i] = elements[i - 1];
   elements[position] = elt;
-  list->count = count + 1;
   return INDEX_TO_NODE (position);
 }
 
-- 
2.52.0

>From 1479336e8a3147b05adcc6f6aaffbddd2da772a8 Mon Sep 17 00:00:00 2001
From: Bruno Haible <[email protected]>
Date: Sun, 3 May 2026 13:50:43 +0200
Subject: [PATCH 05/24] array-map: Use the counted_by attribute.

* lib/gl_array_map.c (struct gl_map_impl): Mark the pairs field as
counted_by count. Swap these fields (needed for clang).
(gl_array_nx_getput): Increase map->count before writing into
map->pairs.
---
 ChangeLog          | 8 ++++++++
 lib/gl_array_map.c | 7 ++++---
 2 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 7bb7e0b36d..212bdd4514 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2026-05-03  Bruno Haible  <[email protected]>
+
+	array-map: Use the counted_by attribute.
+	* lib/gl_array_map.c (struct gl_map_impl): Mark the pairs field as
+	counted_by count. Swap these fields (needed for clang).
+	(gl_array_nx_getput): Increase map->count before writing into
+	map->pairs.
+
 2026-05-03  Bruno Haible  <[email protected]>
 
 	array-list: Use the counted_by attribute.
diff --git a/lib/gl_array_map.c b/lib/gl_array_map.c
index efcff86177..e4c897fffd 100644
--- a/lib/gl_array_map.c
+++ b/lib/gl_array_map.c
@@ -38,10 +38,11 @@ struct pair
 struct gl_map_impl
 {
   struct gl_map_impl_base base;
+  size_t count;
   /* An array of ALLOCATED pairs, of which the first COUNT are used.
      0 <= COUNT <= ALLOCATED.  */
-  struct pair *pairs;
-  size_t count;
+  struct pair *pairs
+    _GL_ATTRIBUTE_COUNTED_BY (count);
   size_t allocated;
 };
 
@@ -150,9 +151,9 @@ gl_array_nx_getput (gl_map_t map, const void *key, const void *value,
         if (grow (map) < 0)
           return -1;
       struct pair *pairs = map->pairs;
+      map->count = count + 1;
       pairs[count].key = key;
       pairs[count].value = value;
-      map->count = count + 1;
       return 1;
     }
 }
-- 
2.52.0

>From ee56d8bca55a0d841d622a76382dfd3025884942 Mon Sep 17 00:00:00 2001
From: Bruno Haible <[email protected]>
Date: Sun, 3 May 2026 13:52:05 +0200
Subject: [PATCH 06/24] array-omap: Use the counted_by attribute.

* lib/gl_array_omap.c (struct gl_omap_impl): Mark the pairs field as
counted_by count. Swap these fields (needed for clang).
(gl_array_nx_add_at): Increase map->count before writing into
map->pairs.
---
 ChangeLog           | 8 ++++++++
 lib/gl_array_omap.c | 7 ++++---
 2 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 212bdd4514..36c0ec442b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2026-05-03  Bruno Haible  <[email protected]>
+
+	array-omap: Use the counted_by attribute.
+	* lib/gl_array_omap.c (struct gl_omap_impl): Mark the pairs field as
+	counted_by count. Swap these fields (needed for clang).
+	(gl_array_nx_add_at): Increase map->count before writing into
+	map->pairs.
+
 2026-05-03  Bruno Haible  <[email protected]>
 
 	array-map: Use the counted_by attribute.
diff --git a/lib/gl_array_omap.c b/lib/gl_array_omap.c
index 600ac472c8..be1b9151ad 100644
--- a/lib/gl_array_omap.c
+++ b/lib/gl_array_omap.c
@@ -37,10 +37,11 @@ struct pair
 struct gl_omap_impl
 {
   struct gl_omap_impl_base base;
+  size_t count;
   /* An array of ALLOCATED pairs, of which the first COUNT are used.
      0 <= COUNT <= ALLOCATED.  */
-  struct pair *pairs;
-  size_t count;
+  struct pair *pairs
+    _GL_ATTRIBUTE_COUNTED_BY (count);
   size_t allocated;
 };
 
@@ -205,11 +206,11 @@ gl_array_nx_add_at (gl_omap_t map, size_t position,
     if (grow (map) < 0)
       return -1;
   struct pair *pairs = map->pairs;
+  map->count = count + 1;
   for (size_t i = count; i > position; i--)
     pairs[i] = pairs[i - 1];
   pairs[position].key = key;
   pairs[position].value = value;
-  map->count = count + 1;
   return 1;
 }
 
-- 
2.52.0

>From 7ad44b611974bc8abcbf402c31fdf901b1128d7f Mon Sep 17 00:00:00 2001
From: Bruno Haible <[email protected]>
Date: Sun, 3 May 2026 13:54:51 +0200
Subject: [PATCH 08/24] array-set: Use the counted_by attribute.

* lib/gl_array_set.c (struct gl_set_impl): Mark the elements field as
counted_by count. Swap these fields (needed for clang).
(gl_array_nx_add): Increase set->count before writing into
set->elements.
---
 ChangeLog          | 8 ++++++++
 lib/gl_array_set.c | 7 ++++---
 2 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 3d2089cc76..453e2ac22b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2026-05-03  Bruno Haible  <[email protected]>
+
+	array-set: Use the counted_by attribute.
+	* lib/gl_array_set.c (struct gl_set_impl): Mark the elements field as
+	counted_by count. Swap these fields (needed for clang).
+	(gl_array_nx_add): Increase set->count before writing into
+	set->elements.
+
 2026-05-03  Bruno Haible  <[email protected]>
 
 	array-oset: Use the counted_by attribute.
diff --git a/lib/gl_array_set.c b/lib/gl_array_set.c
index e34d5962a1..0348627fb7 100644
--- a/lib/gl_array_set.c
+++ b/lib/gl_array_set.c
@@ -32,10 +32,11 @@
 struct gl_set_impl
 {
   struct gl_set_impl_base base;
+  size_t count;
   /* An array of ALLOCATED elements, of which the first COUNT are used.
      0 <= COUNT <= ALLOCATED.  */
-  const void **elements;
-  size_t count;
+  const void **elements
+    _GL_ATTRIBUTE_COUNTED_BY (count);
   size_t allocated;
 };
 
@@ -124,8 +125,8 @@ gl_array_nx_add (gl_set_t set, const void *elt)
       if (count == set->allocated)
         if (grow (set) < 0)
           return -1;
-      set->elements[count] = elt;
       set->count = count + 1;
+      set->elements[count] = elt;
       return 1;
     }
 }
-- 
2.52.0

>From e344eb340847f765849a9d30379164cf4084823a Mon Sep 17 00:00:00 2001
From: Bruno Haible <[email protected]>
Date: Sun, 3 May 2026 13:53:34 +0200
Subject: [PATCH 07/24] array-oset: Use the counted_by attribute.

* lib/gl_array_oset.c (struct gl_oset_impl): Mark the elements field as
counted_by count. Swap these fields (needed for clang).
(gl_array_nx_add_at): Increase set->count before writing into
set->elements.
---
 ChangeLog           | 8 ++++++++
 lib/gl_array_oset.c | 7 ++++---
 2 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 36c0ec442b..3d2089cc76 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2026-05-03  Bruno Haible  <[email protected]>
+
+	array-oset: Use the counted_by attribute.
+	* lib/gl_array_oset.c (struct gl_oset_impl): Mark the elements field as
+	counted_by count. Swap these fields (needed for clang).
+	(gl_array_nx_add_at): Increase set->count before writing into
+	set->elements.
+
 2026-05-03  Bruno Haible  <[email protected]>
 
 	array-omap: Use the counted_by attribute.
diff --git a/lib/gl_array_oset.c b/lib/gl_array_oset.c
index f6c0ee4257..5672e1e4c0 100644
--- a/lib/gl_array_oset.c
+++ b/lib/gl_array_oset.c
@@ -31,10 +31,11 @@
 struct gl_oset_impl
 {
   struct gl_oset_impl_base base;
+  size_t count;
   /* An array of ALLOCATED elements, of which the first COUNT are used.
      0 <= COUNT <= ALLOCATED.  */
-  const void **elements;
-  size_t count;
+  const void **elements
+    _GL_ATTRIBUTE_COUNTED_BY (count);
   size_t allocated;
 };
 
@@ -208,10 +209,10 @@ gl_array_nx_add_at (gl_oset_t set, size_t position, const void *elt)
     if (grow (set) < 0)
       return -1;
   const void **elements = set->elements;
+  set->count = count + 1;
   for (size_t i = count; i > position; i--)
     elements[i] = elements[i - 1];
   elements[position] = elt;
-  set->count = count + 1;
   return 1;
 }
 
-- 
2.52.0

>From 00023475038a2a47f70e3e224f65d61a62669e31 Mon Sep 17 00:00:00 2001
From: Bruno Haible <[email protected]>
Date: Sun, 3 May 2026 13:58:53 +0200
Subject: [PATCH 09/24] carray-list: Use the counted_by attribute.

* lib/gl_carray_list.c (struct gl_list_impl): Mark the elements field as
counted_by allocated. Swap these fields (needed for clang).
---
 ChangeLog            | 6 ++++++
 lib/gl_carray_list.c | 5 +++--
 2 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 453e2ac22b..08307dec69 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2026-05-03  Bruno Haible  <[email protected]>
+
+	carray-list: Use the counted_by attribute.
+	* lib/gl_carray_list.c (struct gl_list_impl): Mark the elements field as
+	counted_by allocated. Swap these fields (needed for clang).
+
 2026-05-03  Bruno Haible  <[email protected]>
 
 	array-set: Use the counted_by attribute.
diff --git a/lib/gl_carray_list.c b/lib/gl_carray_list.c
index b1d2091c33..821b47dc82 100644
--- a/lib/gl_carray_list.c
+++ b/lib/gl_carray_list.c
@@ -34,14 +34,15 @@
 struct gl_list_impl
 {
   struct gl_list_impl_base base;
+  size_t allocated;
   /* An array of ALLOCATED elements, of which the elements
      OFFSET, (OFFSET + 1) % ALLOCATED, ..., (OFFSET + COUNT - 1) % ALLOCATED
      are used.  0 <= COUNT <= ALLOCATED.  Either OFFSET = ALLOCATED = 0 or
      0 <= OFFSET < ALLOCATED.  */
-  const void **elements;
+  const void **elements
+    _GL_ATTRIBUTE_COUNTED_BY (allocated);
   size_t offset;
   size_t count;
-  size_t allocated;
 };
 
 /* struct gl_list_node_impl doesn't exist here.  The pointers are actually
-- 
2.52.0

>From 3df9402a0dd2feb03fc06fa343daadc09fdbb60b Mon Sep 17 00:00:00 2001
From: Bruno Haible <[email protected]>
Date: Sun, 3 May 2026 14:07:23 +0200
Subject: [PATCH 10/24] avltreehash-list: Use the counted_by attribute.

* lib/gl_anyavltree_list1.h (struct gl_list_impl): Mark the table field
as counted_by table_size. Swap these fields (needed for clang).
---
 ChangeLog                 | 6 ++++++
 lib/gl_anyavltree_list1.h | 3 ++-
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/ChangeLog b/ChangeLog
index 08307dec69..84b05af28e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2026-05-03  Bruno Haible  <[email protected]>
+
+	avltreehash-list: Use the counted_by attribute.
+	* lib/gl_anyavltree_list1.h (struct gl_list_impl): Mark the table field
+	as counted_by table_size. Swap these fields (needed for clang).
+
 2026-05-03  Bruno Haible  <[email protected]>
 
 	carray-list: Use the counted_by attribute.
diff --git a/lib/gl_anyavltree_list1.h b/lib/gl_anyavltree_list1.h
index 7c430fa077..760d56d61b 100644
--- a/lib/gl_anyavltree_list1.h
+++ b/lib/gl_anyavltree_list1.h
@@ -56,8 +56,9 @@ struct gl_list_impl
   struct gl_list_impl_base base;
 #if WITH_HASHTABLE
   /* A hash table: managed as an array of collision lists.  */
-  struct gl_hash_entry **table;
   size_t table_size;
+  struct gl_hash_entry **table
+    _GL_ATTRIBUTE_COUNTED_BY (table_size);
 #endif
   struct gl_list_node_impl *root;   /* root node or NULL */
 };
-- 
2.52.0

>From 18421326496569c561a92defe2b57186945bdcf6 Mon Sep 17 00:00:00 2001
From: Bruno Haible <[email protected]>
Date: Sun, 3 May 2026 14:08:20 +0200
Subject: [PATCH 11/24] rbtreehash-list: Use the counted_by attribute.

* lib/gl_anyrbtree_list1.h (struct gl_list_impl): Mark the table field
as counted_by table_size. Swap these fields (needed for clang).
---
 ChangeLog                | 6 ++++++
 lib/gl_anyrbtree_list1.h | 3 ++-
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/ChangeLog b/ChangeLog
index 84b05af28e..b1409d1dee 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2026-05-03  Bruno Haible  <[email protected]>
+
+	rbtreehash-list: Use the counted_by attribute.
+	* lib/gl_anyrbtree_list1.h (struct gl_list_impl): Mark the table field
+	as counted_by table_size. Swap these fields (needed for clang).
+
 2026-05-03  Bruno Haible  <[email protected]>
 
 	avltreehash-list: Use the counted_by attribute.
diff --git a/lib/gl_anyrbtree_list1.h b/lib/gl_anyrbtree_list1.h
index 2f9433476d..408b3db8b3 100644
--- a/lib/gl_anyrbtree_list1.h
+++ b/lib/gl_anyrbtree_list1.h
@@ -61,8 +61,9 @@ struct gl_list_impl
   struct gl_list_impl_base base;
 #if WITH_HASHTABLE
   /* A hash table: managed as an array of collision lists.  */
-  struct gl_hash_entry **table;
   size_t table_size;
+  struct gl_hash_entry **table
+    _GL_ATTRIBUTE_COUNTED_BY (table_size);
 #endif
   struct gl_list_node_impl *root;   /* root node or NULL */
 };
-- 
2.52.0

>From 552aa1aadd010c66ec517a2b757cee914315a0b7 Mon Sep 17 00:00:00 2001
From: Bruno Haible <[email protected]>
Date: Sun, 3 May 2026 14:12:41 +0200
Subject: [PATCH 12/24] linkedhash-list: Use the counted_by attribute.

* lib/gl_anylinked_list1.h (struct gl_list_impl): Mark the table field
as counted_by table_size. Swap these fields (needed for clang).
---
 ChangeLog                | 6 ++++++
 lib/gl_anylinked_list1.h | 3 ++-
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/ChangeLog b/ChangeLog
index b1409d1dee..01804b3f35 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2026-05-03  Bruno Haible  <[email protected]>
+
+	linkedhash-list: Use the counted_by attribute.
+	* lib/gl_anylinked_list1.h (struct gl_list_impl): Mark the table field
+	as counted_by table_size. Swap these fields (needed for clang).
+
 2026-05-03  Bruno Haible  <[email protected]>
 
 	rbtreehash-list: Use the counted_by attribute.
diff --git a/lib/gl_anylinked_list1.h b/lib/gl_anylinked_list1.h
index 4cebac4b8d..f56d455933 100644
--- a/lib/gl_anylinked_list1.h
+++ b/lib/gl_anylinked_list1.h
@@ -36,8 +36,9 @@ struct gl_list_impl
   struct gl_list_impl_base base;
 #if WITH_HASHTABLE
   /* A hash table: managed as an array of collision lists.  */
-  struct gl_hash_entry **table;
   size_t table_size;
+  struct gl_hash_entry **table
+    _GL_ATTRIBUTE_COUNTED_BY (table_size);
 #endif
   /* A circular list anchored at root.
      The first node is = root.next, the last node is = root.prev.
-- 
2.52.0

>From 0780323b60526823af1a0e1446acc341c0826582 Mon Sep 17 00:00:00 2001
From: Bruno Haible <[email protected]>
Date: Sun, 3 May 2026 14:14:01 +0200
Subject: [PATCH 13/24] hash-map: Use the counted_by attribute.

* lib/gl_hash_map.c (struct gl_map_impl): Mark the table field as
counted_by table_size. Swap these fields (needed for clang).
---
 ChangeLog         | 6 ++++++
 lib/gl_hash_map.c | 3 ++-
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/ChangeLog b/ChangeLog
index 01804b3f35..48671e99d4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2026-05-03  Bruno Haible  <[email protected]>
+
+	hash-map: Use the counted_by attribute.
+	* lib/gl_hash_map.c (struct gl_map_impl): Mark the table field as
+	counted_by table_size. Swap these fields (needed for clang).
+
 2026-05-03  Bruno Haible  <[email protected]>
 
 	linkedhash-list: Use the counted_by attribute.
diff --git a/lib/gl_hash_map.c b/lib/gl_hash_map.c
index 049294632b..03057a3de4 100644
--- a/lib/gl_hash_map.c
+++ b/lib/gl_hash_map.c
@@ -44,8 +44,9 @@ struct gl_map_impl
   struct gl_map_impl_base base;
   gl_mapkey_hashcode_fn hashcode_fn;
   /* A hash table: managed as an array of collision lists.  */
-  struct gl_hash_entry **table;
   size_t table_size;
+  struct gl_hash_entry **table
+    _GL_ATTRIBUTE_COUNTED_BY (table_size);
   /* Number of hash table entries.  */
   size_t count;
 };
-- 
2.52.0

>From 5d1750ac305403817539acc6955f76c3e35d6caf Mon Sep 17 00:00:00 2001
From: Bruno Haible <[email protected]>
Date: Sun, 3 May 2026 14:14:52 +0200
Subject: [PATCH 14/24] linkedhash-map: Use the counted_by attribute.

* lib/gl_linkedhash_map.c (struct gl_map_impl): Mark the table field as
counted_by table_size. Swap these fields (needed for clang).
---
 ChangeLog               | 6 ++++++
 lib/gl_linkedhash_map.c | 3 ++-
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/ChangeLog b/ChangeLog
index 48671e99d4..c2a718e294 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2026-05-03  Bruno Haible  <[email protected]>
+
+	linkedhash-map: Use the counted_by attribute.
+	* lib/gl_linkedhash_map.c (struct gl_map_impl): Mark the table field as
+	counted_by table_size. Swap these fields (needed for clang).
+
 2026-05-03  Bruno Haible  <[email protected]>
 
 	hash-map: Use the counted_by attribute.
diff --git a/lib/gl_linkedhash_map.c b/lib/gl_linkedhash_map.c
index 59cef731e0..d1839643ca 100644
--- a/lib/gl_linkedhash_map.c
+++ b/lib/gl_linkedhash_map.c
@@ -46,8 +46,9 @@ struct gl_map_impl
   struct gl_map_impl_base base;
   gl_mapkey_hashcode_fn hashcode_fn;
   /* A hash table: managed as an array of collision lists.  */
-  struct gl_hash_entry **table;
   size_t table_size;
+  struct gl_hash_entry **table
+    _GL_ATTRIBUTE_COUNTED_BY (table_size);
   /* A circular list anchored at root.
      The first node is = root.next, the last node is = root.prev.
      The root's value is unused.  */
-- 
2.52.0

>From 760b4c54a6c722434b2cfadc58623595c3d5bb9e Mon Sep 17 00:00:00 2001
From: Bruno Haible <[email protected]>
Date: Sun, 3 May 2026 14:15:54 +0200
Subject: [PATCH 15/24] hash-set: Use the counted_by attribute.

* lib/gl_hash_set.c (struct gl_set_impl): Mark the table field as
counted_by table_size. Swap these fields (needed for clang).
---
 ChangeLog         | 6 ++++++
 lib/gl_hash_set.c | 3 ++-
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/ChangeLog b/ChangeLog
index c2a718e294..cec5909367 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2026-05-03  Bruno Haible  <[email protected]>
+
+	hash-set: Use the counted_by attribute.
+	* lib/gl_hash_set.c (struct gl_set_impl): Mark the table field as
+	counted_by table_size. Swap these fields (needed for clang).
+
 2026-05-03  Bruno Haible  <[email protected]>
 
 	linkedhash-map: Use the counted_by attribute.
diff --git a/lib/gl_hash_set.c b/lib/gl_hash_set.c
index a1c932975c..945ce46d8d 100644
--- a/lib/gl_hash_set.c
+++ b/lib/gl_hash_set.c
@@ -43,8 +43,9 @@ struct gl_set_impl
   struct gl_set_impl_base base;
   gl_setelement_hashcode_fn hashcode_fn;
   /* A hash table: managed as an array of collision lists.  */
-  struct gl_hash_entry **table;
   size_t table_size;
+  struct gl_hash_entry **table
+    _GL_ATTRIBUTE_COUNTED_BY (table_size);
   /* Number of hash table entries.  */
   size_t count;
 };
-- 
2.52.0

>From a0fa851e6c403ed6fdf9c4750f75a03ca2520784 Mon Sep 17 00:00:00 2001
From: Bruno Haible <[email protected]>
Date: Sun, 3 May 2026 14:16:26 +0200
Subject: [PATCH 16/24] linkedhash-set: Use the counted_by attribute.

* lib/gl_linkedhash_set.c (struct gl_set_impl): Mark the table field as
counted_by table_size. Swap these fields (needed for clang).
---
 ChangeLog               | 6 ++++++
 lib/gl_linkedhash_set.c | 3 ++-
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/ChangeLog b/ChangeLog
index cec5909367..8434467b18 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2026-05-03  Bruno Haible  <[email protected]>
+
+	linkedhash-set: Use the counted_by attribute.
+	* lib/gl_linkedhash_set.c (struct gl_set_impl): Mark the table field as
+	counted_by table_size. Swap these fields (needed for clang).
+
 2026-05-03  Bruno Haible  <[email protected]>
 
 	hash-set: Use the counted_by attribute.
diff --git a/lib/gl_linkedhash_set.c b/lib/gl_linkedhash_set.c
index 303b33865a..97f8efc682 100644
--- a/lib/gl_linkedhash_set.c
+++ b/lib/gl_linkedhash_set.c
@@ -45,8 +45,9 @@ struct gl_set_impl
   struct gl_set_impl_base base;
   gl_setelement_hashcode_fn hashcode_fn;
   /* A hash table: managed as an array of collision lists.  */
-  struct gl_hash_entry **table;
   size_t table_size;
+  struct gl_hash_entry **table
+    _GL_ATTRIBUTE_COUNTED_BY (table_size);
   /* A circular list anchored at root.
      The first node is = root.next, the last node is = root.prev.
      The root's value is unused.  */
-- 
2.52.0

>From b71975ebcbef81fb8b81b826c1f3b866d66891d9 Mon Sep 17 00:00:00 2001
From: Bruno Haible <[email protected]>
Date: Sun, 3 May 2026 14:35:18 +0200
Subject: [PATCH 18/24] linebuffer: Use the counted_by attribute.

* lib/linebuffer.h (struct linebuffer): Mark the buffer field as
counted_by size.
---
 ChangeLog        | 6 ++++++
 lib/linebuffer.h | 3 ++-
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/ChangeLog b/ChangeLog
index d47df5b358..ca1cecc4dc 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2026-05-03  Bruno Haible  <[email protected]>
+
+	linebuffer: Use the counted_by attribute.
+	* lib/linebuffer.h (struct linebuffer): Mark the buffer field as
+	counted_by size.
+
 2026-05-03  Bruno Haible  <[email protected]>
 
 	hash: Use the counted_by attribute.
diff --git a/lib/linebuffer.h b/lib/linebuffer.h
index af22d27b36..839838feb1 100644
--- a/lib/linebuffer.h
+++ b/lib/linebuffer.h
@@ -33,7 +33,8 @@ struct linebuffer
 {
   idx_t size;                  /* Allocated. */
   idx_t length;                /* Used. */
-  char *buffer;
+  char *buffer
+    _GL_ATTRIBUTE_COUNTED_BY (size);
 };
 
 /* Initialize linebuffer LINEBUFFER for use. */
-- 
2.52.0

>From 65e42b2c13854432daba2dd036a536a496090423 Mon Sep 17 00:00:00 2001
From: Bruno Haible <[email protected]>
Date: Sun, 3 May 2026 14:27:16 +0200
Subject: [PATCH 17/24] hash: Use the counted_by attribute.

* lib/hash.c (struct hash_table): Mark the bucket field as counted_by
n_buckets. Swap these fields (needed for clang, see
<https://discourse.llvm.org/t/rfc-forward-referencing-a-struct-member-within-bounds-annotations/85510>).
---
 ChangeLog  | 7 +++++++
 lib/hash.c | 5 +++--
 2 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 8434467b18..d47df5b358 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2026-05-03  Bruno Haible  <[email protected]>
+
+	hash: Use the counted_by attribute.
+	* lib/hash.c (struct hash_table): Mark the bucket field as counted_by
+	n_buckets. Swap these fields (needed for clang, see
+	<https://discourse.llvm.org/t/rfc-forward-referencing-a-struct-member-within-bounds-annotations/85510>).
+
 2026-05-03  Bruno Haible  <[email protected]>
 
 	linkedhash-set: Use the counted_by attribute.
diff --git a/lib/hash.c b/lib/hash.c
index 23ebc66bc5..d428a26a19 100644
--- a/lib/hash.c
+++ b/lib/hash.c
@@ -55,12 +55,13 @@ struct hash_entry
 
 struct hash_table
   {
+    size_t n_buckets;
     /* The array of buckets starts at BUCKET and extends to BUCKET_LIMIT-1,
        for a possibility of N_BUCKETS.  Among those, N_BUCKETS_USED buckets
        are not empty, there are N_ENTRIES active entries in the table.  */
-    struct hash_entry *bucket;
+    struct hash_entry *bucket
+      _GL_ATTRIBUTE_COUNTED_BY (n_buckets);
     struct hash_entry const *bucket_limit;
-    size_t n_buckets;
     size_t n_buckets_used;
     size_t n_entries;
 
-- 
2.52.0

>From bba72b4e351ff057efc5473a5053faaba2d35596 Mon Sep 17 00:00:00 2001
From: Bruno Haible <[email protected]>
Date: Sun, 3 May 2026 14:46:15 +0200
Subject: [PATCH 19/24] mbfile: Add comments regarding the counted_by
 attribute.

* lib/mbfile.h (struct mbfile_multi): Clarify how many elements of the
fields buf and pushback are used.
---
 ChangeLog    | 6 ++++++
 lib/mbfile.h | 4 ++--
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index ca1cecc4dc..f0db5a714a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2026-05-03  Bruno Haible  <[email protected]>
+
+	mbfile: Add comments regarding the counted_by attribute.
+	* lib/mbfile.h (struct mbfile_multi): Clarify how many elements of the
+	fields buf and pushback are used.
+
 2026-05-03  Bruno Haible  <[email protected]>
 
 	linebuffer: Use the counted_by attribute.
diff --git a/lib/mbfile.h b/lib/mbfile.h
index c88fcffa96..040feae64f 100644
--- a/lib/mbfile.h
+++ b/lib/mbfile.h
@@ -79,8 +79,8 @@ struct mbfile_multi {
   unsigned int pushback_count; /* <= MBFILE_MAX_PUSHBACK */
   mbstate_t state;
   unsigned int bufcount;
-  char buf[MBCHAR_BUF_SIZE];
-  struct mbchar pushback[MBFILE_MAX_PUSHBACK];
+  char buf[MBCHAR_BUF_SIZE]; /* COUNTED_BY (bufcount) */
+  struct mbchar pushback[MBFILE_MAX_PUSHBACK]; /* COUNTED_BY (pushback_count) */
 };
 
 MBFILE_INLINE void
-- 
2.52.0

>From 2f29969549a3d26f7aad1b34334f1e5494792c4e Mon Sep 17 00:00:00 2001
From: Bruno Haible <[email protected]>
Date: Sun, 3 May 2026 14:58:41 +0200
Subject: [PATCH 20/24] readtokens: Use the counted_by attribute.

* lib/readtokens.h (struct tokenbuffer): Mark the buffer field as
counted_by size.
---
 ChangeLog        | 6 ++++++
 lib/readtokens.h | 3 ++-
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/ChangeLog b/ChangeLog
index f0db5a714a..0d37729605 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2026-05-03  Bruno Haible  <[email protected]>
+
+	readtokens: Use the counted_by attribute.
+	* lib/readtokens.h (struct tokenbuffer): Mark the buffer field as
+	counted_by size.
+
 2026-05-03  Bruno Haible  <[email protected]>
 
 	mbfile: Add comments regarding the counted_by attribute.
diff --git a/lib/readtokens.h b/lib/readtokens.h
index de83f996fc..a47a96ede7 100644
--- a/lib/readtokens.h
+++ b/lib/readtokens.h
@@ -33,7 +33,8 @@ extern "C" {
 struct tokenbuffer
 {
   size_t size;
-  char *buffer;
+  char *buffer
+    _GL_ATTRIBUTE_COUNTED_BY (size);
 };
 typedef struct tokenbuffer token_buffer;
 
-- 
2.52.0

>From 5a14d37f8011f273975b7f91dbc21a37eedee310 Mon Sep 17 00:00:00 2001
From: Bruno Haible <[email protected]>
Date: Sun, 3 May 2026 15:05:21 +0200
Subject: [PATCH 21/24] ssfmalloc: Use the counted_by attribute.

* lib/ssfmalloc.h (struct medium_page_header): Mark the gaps field as
counted_by num_gaps.
(allocate_medium_block_in_page): Increase pageptr->num_gaps before
writing into pageptr->gaps.
---
 ChangeLog       | 8 ++++++++
 lib/ssfmalloc.h | 8 +++++---
 2 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 0d37729605..2b86ef0afc 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2026-05-03  Bruno Haible  <[email protected]>
+
+	ssfmalloc: Use the counted_by attribute.
+	* lib/ssfmalloc.h (struct medium_page_header): Mark the gaps field as
+	counted_by num_gaps.
+	(allocate_medium_block_in_page): Increase pageptr->num_gaps before
+	writing into pageptr->gaps.
+
 2026-05-03  Bruno Haible  <[email protected]>
 
 	readtokens: Use the counted_by attribute.
diff --git a/lib/ssfmalloc.h b/lib/ssfmalloc.h
index a495895603..f04f6e9ccf 100644
--- a/lib/ssfmalloc.h
+++ b/lib/ssfmalloc.h
@@ -215,7 +215,8 @@ struct page_pool
      updated in the managed_pages tree so far.  */
   #define UPDATE_QUEUE_SIZE 10
   unsigned int update_queue_count; /* <= UPDATE_QUEUE_SIZE */
-  uintptr_t update_queue[UPDATE_QUEUE_SIZE];
+  uintptr_t update_queue[UPDATE_QUEUE_SIZE]
+    /* COUNTED_BY (update_queue_count) */;
 
   /* A page that could be freed.
      We don't free it immediately, so that on allocation/deallocation
@@ -528,7 +529,8 @@ struct medium_page_header
   /* If n blocks are allocated, there are n+1 gaps before, between, and
      after them.  Keep them in an array, sorted in ascending order.  */
   unsigned int num_gaps; /* > 0 */
-  struct memory_range gaps[FLEXIBLE_ARRAY_MEMBER /* PAGESIZE / SMALL_BLOCK_MAX_SIZE + 1 */];
+  struct memory_range gaps[FLEXIBLE_ARRAY_MEMBER /* PAGESIZE / SMALL_BLOCK_MAX_SIZE + 1 */]
+    _GL_ATTRIBUTE_COUNTED_BY (num_gaps);
 };
 
 #define MEDIUM_BLOCKS_PAGE_MAX_GAPS \
@@ -599,6 +601,7 @@ allocate_medium_block_in_page (size_t size, uintptr_t page)
     abort ();
 
   /* Split the gap, leaving an empty gap and a remaining gap.  */
+  pageptr->num_gaps = num_gaps + 1;
   for (size_t i = num_gaps - 1; ; i--)
     {
       pageptr->gaps[i + 1] = pageptr->gaps[i];
@@ -608,7 +611,6 @@ allocate_medium_block_in_page (size_t size, uintptr_t page)
   size_t result = pageptr->gaps[best_i].start;
   pageptr->gaps[best_i].end = result;
   pageptr->gaps[best_i + 1].start = result + aligned_size;
-  pageptr->num_gaps = num_gaps + 1;
   if (pageptr->num_gaps > PAGESIZE / SMALL_BLOCK_MAX_SIZE + 1)
     /* Invalid state: More gaps than expected.  */
     abort ();
-- 
2.52.0

>From b13f1c30cba8cca762716ecd5771eea928e01f1a Mon Sep 17 00:00:00 2001
From: Bruno Haible <[email protected]>
Date: Sun, 3 May 2026 15:19:52 +0200
Subject: [PATCH 22/24] string-desc: Use the counted_by attribute.

* lib/string-desc.h (struct rw_string_desc_t, struct string_desc_t):
Mark the _data field as counted_by _nbytes.
---
 ChangeLog         | 6 ++++++
 lib/string-desc.h | 6 ++++--
 2 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 2b86ef0afc..0293fa1543 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2026-05-03  Bruno Haible  <[email protected]>
+
+	string-desc: Use the counted_by attribute.
+	* lib/string-desc.h (struct rw_string_desc_t, struct string_desc_t):
+	Mark the _data field as counted_by _nbytes.
+
 2026-05-03  Bruno Haible  <[email protected]>
 
 	ssfmalloc: Use the counted_by attribute.
diff --git a/lib/string-desc.h b/lib/string-desc.h
index f716f0e27c..ab4c6392b7 100644
--- a/lib/string-desc.h
+++ b/lib/string-desc.h
@@ -127,7 +127,8 @@ struct rw_string_desc_t
 {
   /* The fields of this struct should be considered private.  */
   idx_t _nbytes;
-  char *_data;
+  char *_data
+    _GL_ATTRIBUTE_COUNTED_BY (_nbytes);
 };
 #if HAVE_RW_STRING_DESC
 typedef struct string_desc_t string_desc_t;
@@ -135,7 +136,8 @@ struct string_desc_t
 {
   /* The fields of this struct should be considered private.  */
   idx_t _nbytes;
-  const char *_data;
+  const char *_data
+    _GL_ATTRIBUTE_COUNTED_BY (_nbytes);
 };
 #else
 typedef rw_string_desc_t string_desc_t;
-- 
2.52.0

>From e08bd1d0241fd220af07fd783e01a04c7b08cfb9 Mon Sep 17 00:00:00 2001
From: Bruno Haible <[email protected]>
Date: Sun, 3 May 2026 15:22:52 +0200
Subject: [PATCH 23/24] windows-spawn: Use the counted_by attribute.

* lib/windows-spawn.h (struct inheritable_handles): Mark the ih field as
counted_by count.
---
 ChangeLog           | 6 ++++++
 lib/windows-spawn.h | 3 ++-
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/ChangeLog b/ChangeLog
index 0293fa1543..899e26f08e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2026-05-03  Bruno Haible  <[email protected]>
+
+	windows-spawn: Use the counted_by attribute.
+	* lib/windows-spawn.h (struct inheritable_handles): Mark the ih field as
+	counted_by count.
+
 2026-05-03  Bruno Haible  <[email protected]>
 
 	string-desc: Use the counted_by attribute.
diff --git a/lib/windows-spawn.h b/lib/windows-spawn.h
index f713bd9deb..4ac1e2a3b2 100644
--- a/lib/windows-spawn.h
+++ b/lib/windows-spawn.h
@@ -141,7 +141,8 @@ struct inheritable_handles
   /* The number of allocated entries in the two arrays below.  */
   size_t allocated;
   /* ih[0..count-1] are the occupied entries.  */
-  struct IHANDLE *ih;
+  struct IHANDLE *ih
+    _GL_ATTRIBUTE_COUNTED_BY (count);
 };
 
 /* Initializes a set of inheritable handles, filling in all or part of the
-- 
2.52.0

>From 4d1444ca550024fafa85ed3710fab2fd32a1b775 Mon Sep 17 00:00:00 2001
From: Bruno Haible <[email protected]>
Date: Sun, 3 May 2026 15:30:59 +0200
Subject: [PATCH 24/24] acl-permissions: Use the counted_by attribute.

* lib/acl-internal.h (struct permission_context): On Solaris, mark the
entries field as counted_by count and the ace_entries field as
counted_by ace_count.
---
 ChangeLog          |  7 +++++++
 lib/acl-internal.h | 12 +++++++-----
 2 files changed, 14 insertions(+), 5 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 899e26f08e..93ea77b811 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2026-05-03  Bruno Haible  <[email protected]>
+
+	acl-permissions: Use the counted_by attribute.
+	* lib/acl-internal.h (struct permission_context): On Solaris, mark the
+	entries field as counted_by count and the ace_entries field as
+	counted_by ace_count.
+
 2026-05-03  Bruno Haible  <[email protected]>
 
 	windows-spawn: Use the counted_by attribute.
diff --git a/lib/acl-internal.h b/lib/acl-internal.h
index 855005bb75..eafb4d027f 100644
--- a/lib/acl-internal.h
+++ b/lib/acl-internal.h
@@ -249,17 +249,19 @@ struct permission_context {
 
 # elif defined GETACL /* Solaris, Cygwin < 2.5 */
   int count;
-  aclent_t *entries;
+  aclent_t *entries
+    _GL_ATTRIBUTE_COUNTED_BY (count);
 #  ifdef ACE_GETACL
   int ace_count;
-  ace_t *ace_entries;
+  ace_t *ace_entries
+    _GL_ATTRIBUTE_COUNTED_BY (ace_count);
 #  endif
 
 # elif HAVE_GETACL /* HP-UX */
-  struct acl_entry entries[NACLENTRIES];
+  struct acl_entry entries[NACLENTRIES] /* COUNTED_BY (count) */;
   int count;
 #  if HAVE_ACLV_H
-  struct acl aclv_entries[NACLVENTRIES];
+  struct acl aclv_entries[NACLVENTRIES] /* COUNTED_BY (aclv_count) */;
   int aclv_count;
 #  endif
 
@@ -268,7 +270,7 @@ struct permission_context {
   bool have_u;
 
 # elif HAVE_ACLSORT /* NonStop Kernel */
-  struct acl entries[NACLENTRIES];
+  struct acl entries[NACLENTRIES] /* COUNTED_BY (count) */;
   int count;
 
 # endif
-- 
2.52.0

Reply via email to