https://github.com/rapidsna created https://github.com/llvm/llvm-project/pull/106147
`-fbounds-safety` doesn't allow taking address of a variable referred to by `__counted_by`, in order to prevent code from using the pointer to update the variable without necessary checks to keep the invariant of `__counted_by`. As shown in the example below, with -fbounds-safety the compiler ensures that the `__counted_by` pointer/or array has at least as many as elements that the attribute indicates, by requiring the count and the buf are always updated side by side and emitting run-time checks to ensure the new values are valid. ``` struct counted_buf { sized_t count; int *__counted_by(count) buf; }; // BEFORE FIX void foo(struct counted_buf *p) { p->count = 10; // error: assignment to 'count' requires corresponding assignment to 'int *__counted_by(count) buf') } // FIXED by adding assignment to `p->buf` void foo(struct counted_buf *p) { // The compiler is now happy because p->buf = (int *)malloc(sizeof(int) *5); // run-time checks are emitted to make sure new buf has at least `10` elements. p->count = 10; } ``` Consequently, `-fbounds-safety` prevents taking address of a variable referred to by `__counted_by`, because otherwise, the compiler cannot check the updates through the pointer pointing to the count: ``` void foo(struct counted_buf *p) { int *count_p = &p->count; // error: variable referred to by '__counted_by' cannot be pointed to by any other variable *count_p = 10; // without the above error, `count_p` is a normal `int *` so the compiler cannot check the value it updates against `__counted_by` } ``` This PR is to explicitly specify this restriction and avoid future conflicts. >From 8ed704c9e85b917d526df1e468e325a302f5a4d2 Mon Sep 17 00:00:00 2001 From: Yeoul Na <yeoul...@apple.com> Date: Mon, 26 Aug 2024 14:17:59 -0700 Subject: [PATCH] Specify taking address of a variable referred to by '__counted_by' is forbidden --- clang/docs/BoundsSafety.rst | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/clang/docs/BoundsSafety.rst b/clang/docs/BoundsSafety.rst index 8fd655663edb00..e4ddd3c62db65d 100644 --- a/clang/docs/BoundsSafety.rst +++ b/clang/docs/BoundsSafety.rst @@ -759,7 +759,24 @@ relationship must hold even after any of these related variables are updated. To this end, the model requires that assignments to ``buf`` and ``count`` must be side by side, with no side effects between them. This prevents ``buf`` and ``count`` from temporarily falling out of sync due to updates happening at a -distance. +distance. In addition, taking address of ``count`` is not allowed in order to +prevent the programmers from updating the ``count`` through the pointer, which +will evade the necessary checks to make ``count`` and ``buf`` in sync. + +.. code-block:: c + + struct counted_buf { + int *__counted_by(count) buf; + size_t count; + }; + + void foo(struct counted_buf *p) { + int *pointer_to_count = &p->count; // error: variable referred to by + // '__counted_by' cannot be pointed to by any other variable; exception is + // when the pointer is passed as a compatible argument to a function. + *pointer_to_count = SIZE_MAX; // Without reporting the error above, the + // compiler cannot prevent count from getting an invalid value. + } The example below shows a function ``alloc_buf`` that initializes a struct that members that use the ``__counted_by`` annotation. The compiler allows these _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits