summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@tavianator.com>2023-05-16 11:37:53 -0400
committerTavian Barnes <tavianator@tavianator.com>2023-05-16 11:37:53 -0400
commit8706515d905038ee7d869ab5ace0471c781d2624 (patch)
tree207b13cc3cb7268cccb984956f164d4b21948eb5
parent8302f1d0441b3105470426105b3031961e066535 (diff)
downloadbfs-8706515d905038ee7d869ab5ace0471c781d2624.tar.xz
config: Align after saturating in flex_sizeof()
This ensures that it's legal to call aligned_alloc() with the result, which requires a multiple of the alignment.
-rw-r--r--src/config.h11
-rw-r--r--tests/bfstd.c3
2 files changed, 11 insertions, 3 deletions
diff --git a/src/config.h b/src/config.h
index b2c58be..47aa529 100644
--- a/src/config.h
+++ b/src/config.h
@@ -141,10 +141,17 @@
#define countof(array) (sizeof(array) / sizeof(0[array]))
/**
+ * Round down to a multiple of an alignment.
+ */
+static inline size_t align_floor(size_t align, size_t size) {
+ return size & ~(align - 1);
+}
+
+/**
* Round up to a multiple of an alignment.
*/
static inline size_t align_ceil(size_t align, size_t size) {
- return (size + align - 1) & ~(align - 1);
+ return align_floor(align, size + align - 1);
}
/**
@@ -171,8 +178,8 @@ static inline size_t flex_sizeof_impl(size_t align, size_t min, size_t offset, s
size_t mask = align - 1;
ret += mask;
overflow |= ret < mask;
- ret &= ~mask;
ret |= -overflow;
+ ret &= ~mask;
// Make sure flex_sizeof(type, member, 0) >= sizeof(type), even if the
// type has more padding than necessary for alignment
diff --git a/tests/bfstd.c b/tests/bfstd.c
index 1917a53..a986a23 100644
--- a/tests/bfstd.c
+++ b/tests/bfstd.c
@@ -41,7 +41,8 @@ int main(void) {
};
assert(flex_sizeof(struct flexible, bar, 0) >= sizeof(struct flexible));
assert(flex_sizeof(struct flexible, bar, 16) % alignof(struct flexible) == 0);
- assert(flex_sizeof(struct flexible, bar, SIZE_MAX / sizeof(int) + 1) == SIZE_MAX);
+ assert(flex_sizeof(struct flexible, bar, SIZE_MAX / sizeof(int) + 1)
+ == align_floor(alignof(struct flexible), SIZE_MAX));
assert(flex_sizeof_impl(8, 16, 4, 4, 1) == 16);
// From man 3p basename