summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@tavianator.com>2025-05-26 10:26:12 -0400
committerTavian Barnes <tavianator@tavianator.com>2025-05-26 10:45:45 -0400
commit89969b4b0bea3bd4cddf97c989ca63f3a1aaa07c (patch)
tree58a244a7121a0000313b2044c139df2340e72ee1
parent6fa72ff42d95dfd883d59ce7cf6bdc74abebf015 (diff)
downloadbfs-89969b4b0bea3bd4cddf97c989ca63f3a1aaa07c.tar.xz
Add support for __attribute__((counted_by(...)))
-rw-r--r--src/bfs.h9
-rw-r--r--src/bftw.c2
-rw-r--r--src/color.c4
-rw-r--r--src/dstring.c2
-rw-r--r--src/ioq.c4
-rw-r--r--src/trie.c2
-rw-r--r--src/trie.h2
7 files changed, 17 insertions, 8 deletions
diff --git a/src/bfs.h b/src/bfs.h
index 32dbbae..3cee727 100644
--- a/src/bfs.h
+++ b/src/bfs.h
@@ -219,6 +219,15 @@ extern const char bfs_ldlibs[];
#endif
/**
+ * Mark the size of a flexible array member.
+ */
+#if __has_attribute(counted_by)
+# define _counted_by(...) __attribute__((counted_by(__VA_ARGS__)))
+#else
+# define _counted_by(...)
+#endif
+
+/**
* Optimization hint to not unroll a loop.
*/
#if BFS_HAS_PRAGMA_NOUNROLL
diff --git a/src/bftw.c b/src/bftw.c
index 6d1475e..0ca6f34 100644
--- a/src/bftw.c
+++ b/src/bftw.c
@@ -253,7 +253,7 @@ struct bftw_file {
/** The length of the file's name. */
size_t namelen;
/** The file's name. */
- char name[];
+ char name[]; // _counted_by(namelen + 1)
};
/**
diff --git a/src/color.c b/src/color.c
index 588dbac..a026831 100644
--- a/src/color.c
+++ b/src/color.c
@@ -32,7 +32,7 @@ struct esc_seq {
/** The length of the escape sequence. */
size_t len;
/** The escape sequence itself, without a terminating NUL. */
- char seq[];
+ char seq[] _counted_by(len);
};
/**
@@ -48,7 +48,7 @@ struct ext_color {
/** Whether the comparison should be case-sensitive. */
bool case_sensitive;
/** The extension to match (NUL-terminated). */
- char ext[];
+ char ext[]; // _counted_by(len + 1);
};
struct colors {
diff --git a/src/dstring.c b/src/dstring.c
index 0f08679..678d685 100644
--- a/src/dstring.c
+++ b/src/dstring.c
@@ -23,7 +23,7 @@ struct dstring {
/** Length of the string, *excluding* the terminating NUL. */
size_t len;
/** The string itself. */
- alignas(dchar) char str[];
+ alignas(dchar) char str[] _counted_by(cap);
};
#define DSTR_OFFSET offsetof(struct dstring, str)
diff --git a/src/ioq.c b/src/ioq.c
index 1efedd7..57eb4a5 100644
--- a/src/ioq.c
+++ b/src/ioq.c
@@ -203,7 +203,7 @@ struct ioqq {
cache_align atomic size_t tail;
/** The circular buffer itself. */
- cache_align ioq_slot slots[];
+ cache_align ioq_slot slots[]; // _counted_by(slot_mask + 1)
};
/** Destroy an I/O command queue. */
@@ -593,7 +593,7 @@ struct ioq {
/** The number of background threads. */
size_t nthreads;
/** The background threads themselves. */
- struct ioq_thread threads[];
+ struct ioq_thread threads[] _counted_by(nthreads);
};
/** Cancel a request if we need to. */
diff --git a/src/trie.c b/src/trie.c
index 4e0944a..6aac17f 100644
--- a/src/trie.c
+++ b/src/trie.c
@@ -129,7 +129,7 @@ struct trie_node {
* tag to distinguish internal nodes from leaves. This is safe as long
* as all dynamic allocations are aligned to more than a single byte.
*/
- uintptr_t children[];
+ uintptr_t children[]; // _counted_by(count_ones(bitmap))
};
/** Check if an encoded pointer is to an internal node. */
diff --git a/src/trie.h b/src/trie.h
index d8cecab..19bd81d 100644
--- a/src/trie.h
+++ b/src/trie.h
@@ -21,7 +21,7 @@ struct trie_leaf {
/** The length of the key in bytes. */
size_t length;
/** The key itself, stored inline. */
- char key[];
+ char key[] _counted_by(length);
};
/**