[clang] [llvm] [Clang] Correct __builtin_dynamic_object_size for subobject types (PR #83204)

Bill Wendling via cfe-commits cfe-commits at lists.llvm.org
Tue Mar 12 15:16:57 PDT 2024


================
@@ -26996,18 +26996,38 @@ class, structure, array, or other object.
 Arguments:
 """"""""""
 
-The ``llvm.objectsize`` intrinsic takes four arguments. The first argument is a
-pointer to or into the ``object``. The second argument determines whether
-``llvm.objectsize`` returns 0 (if true) or -1 (if false) when the object size is
-unknown. The third argument controls how ``llvm.objectsize`` acts when ``null``
-in address space 0 is used as its pointer argument. If it's ``false``,
-``llvm.objectsize`` reports 0 bytes available when given ``null``. Otherwise, if
-the ``null`` is in a non-zero address space or if ``true`` is given for the
-third argument of ``llvm.objectsize``, we assume its size is unknown. The fourth
-argument to ``llvm.objectsize`` determines if the value should be evaluated at
-runtime.
+The ``llvm.objectsize`` intrinsic takes six arguments:
+
+- The first argument is a pointer to or into the ``object``.
+- The second argument controls which value to return when the size is unknown:
+
+  - If it's ``false``, ``llvm.objectsize`` returns ``-1``.
+  - If it's ``true``, ``llvm.objectsize`` returns ``0``.
+
+- The third argument controls how ``llvm.objectsize`` acts when ``null`` in
+  address space 0 is used as its pointer argument:
+
+  - If it's ``false``, ``llvm.objectsize`` reports 0 bytes available when given
+    ``null``.
+  - If it's ``true``, or the ``null`` pointer is in a non-zero address space,
+    the size is assumed to be unknown.
+
+- The fourth argument to ``llvm.objectsize`` determines if the value should be
+  evaluated at runtime.
+- The fifth argument controls which size ``llvm.objectsize`` returns:
+
+  - If it's ``false``, ``llvm.objectsize`` returns the size of the closest
+    surrounding subobject.
+  - If it's ``true``, ``llvm.objectsize`` returns the size of the whole object.
+
+- If non-zero, the sixth and seventh arguments encode the size and offset
+  information, respectively, of the original subobject's layout and is used
+  when the fifth argument is ``false``.
+- The seventh argument encodes the offset information of the original
+  subobject's layout and is used when the fifth argument is ``false``.
----------------
bwendling wrote:

> in some simple test cases it does appear to work.

Please don't be insulting. I didn't just run a couple of "simple" tests and called it a day. I had many rather convoluted examples and they all worked.

> Sorry, that was a typo in my example: the call in h() should be f(&b.a).

Okay. This patch generates the correct answer (modified so it's calculated by the middle end):

```
$  clang -O2 ~/llvm/a.c && ./a.out
&((char *)&p->n)[idx]:
__builtin_dynamic_object_size(&((char *)&p->n)[idx], 1) = 3

&((char *)&p->n)[idx]:
__builtin_dynamic_object_size(&((char *)&p->n)[idx], 1) = 3
```

> I mean, pass a pointer to the start of the subobject. For example, for p->arr[i], you'd pass in &p->arr.

I don't think that's necessary. If we're given the original size and the middle end is calculating the final size, it may be sufficient to ignore the offset all together for sub-objects. I'll see if it works.

https://github.com/llvm/llvm-project/pull/83204


More information about the cfe-commits mailing list