@@ -5422,16 +5422,85 @@ The ``#pragma comment(lib, ...)`` directive is supported on all ELF targets.
54225422The second parameter is the library name (without the traditional Unix prefix of
54235423``lib ``). This allows you to provide an implicit link of dependent libraries.
54245424
5425- Evaluating Object Size Dynamically
5426- ==================================
5425+ Evaluating Object Size
5426+ ======================
5427+
5428+ Clang supports the builtins ``__builtin_object_size `` and
5429+ ``__builtin_dynamic_object_size ``. The semantics are compatible with GCC's
5430+ builtins of the same names, but the details are slightly different.
5431+
5432+ .. code-block :: c
5433+
5434+ size_t __builtin_[dynamic_]object_size(const void *ptr, int type)
5435+
5436+ Returns the number of accessible bytes ``n `` past ``ptr ``. The value returned
5437+ depends on ``type ``, which is required to be an integer constant between 0 and
5438+ 3:
5439+
5440+ * If ``type & 2 == 0 ``, the least ``n `` is returned such that accesses to
5441+ ``(const char*)ptr + n `` and beyond are known to be out of bounds. This is
5442+ ``(size_t)-1 `` if no better bound is known.
5443+ * If ``type & 2 == 2 ``, the greatest ``n `` is returned such that accesses to
5444+ ``(const char*)ptr + i `` are known to be in bounds, for 0 <= ``i `` < ``n ``.
5445+ This is ``(size_t)0 `` if no better bound is known.
54275446
5428- Clang supports the builtin ``__builtin_dynamic_object_size ``, the semantics are
5429- the same as GCC's ``__builtin_object_size `` (which Clang also supports), but
5430- ``__builtin_dynamic_object_size `` can evaluate the object's size at runtime.
5431- ``__builtin_dynamic_object_size `` is meant to be used as a drop-in replacement
5432- for ``__builtin_object_size `` in libraries that support it.
5447+ .. code-block :: c
5448+
5449+ char small[10], large[100];
5450+ bool cond;
5451+ // Returns 100: writes of more than 100 bytes are known to be out of bounds.
5452+ int n100 = __builtin_object_size(cond ? small : large, 0);
5453+ // Returns 10: writes of 10 or fewer bytes are known to be in bounds.
5454+ int n10 = __builtin_object_size(cond ? small : large, 2);
5455+
5456+ * If ``type & 1 == 0 ``, pointers are considered to be in bounds if they point
5457+ into the same storage as ``ptr `` -- that is, the same stack object, global
5458+ variable, or heap allocation.
5459+ * If ``type & 1 == 1 ``, pointers are considered to be in bounds if they point
5460+ to the same subobject that ``ptr `` points to. If ``ptr `` points to an array
5461+ element, other elements of the same array, but not of enclosing arrays, are
5462+ considered in bounds.
5463+
5464+ .. code-block :: c
5465+
5466+ struct X { char a, b, c; } x;
5467+ static_assert(__builtin_object_size(&x, 0) == 3);
5468+ static_assert(__builtin_object_size(&x.b, 0) == 2);
5469+ static_assert(__builtin_object_size(&x.b, 1) == 1);
5470+
5471+ .. code-block :: c
54335472
5434- For instance, here is a program that ``__builtin_dynamic_object_size `` will make
5473+ char a[10][10][10];
5474+ static_assert(__builtin_object_size(&a, 1) == 1000);
5475+ static_assert(__builtin_object_size(&a[1], 1) == 900);
5476+ static_assert(__builtin_object_size(&a[1][1], 1) == 90);
5477+ static_assert(__builtin_object_size(&a[1][1][1], 1) == 9);
5478+
5479+ The values returned by this builtin are a best effort conservative approximation
5480+ of the correct answers. When ``type & 2 == 0 ``, the true value is less than or
5481+ equal to the value returned by the builtin, and when ``type & 2 == 1 ``, the true
5482+ value is greater than or equal to the value returned by the builtin.
5483+
5484+ For ``__builtin_object_size ``, the value is determined entirely at compile time.
5485+ With optimization enabled, better results will be produced, especially when the
5486+ call to ``__builtin_object_size `` is in a different function from the formation
5487+ of the pointer. Unlike in GCC, enabling optimization in Clang does not allow
5488+ more information about subobjects to be determined, so the ``type & 1 == 1 ``
5489+ case will often give imprecise results when used across a function call boundary
5490+ even when optimization is enabled.
5491+
5492+ `The pass_object_size and pass_dynamic_object_size attributes <https://clang.llvm.org/docs/AttributeReference.html#pass-object-size-pass-dynamic-object-size >`_
5493+ can be used to invisibly pass the object size for a pointer parameter alongside
5494+ the pointer in a function call. This allows more precise object sizes to be
5495+ determined both when building without optimizations and in the ``type & 1 == 1 ``
5496+ case.
5497+
5498+ For ``__builtin_dynamic_object_size ``, the result is not limited to being a
5499+ compile time constant. Instead, a small amount of runtime evaluation is
5500+ permitted to determine the size of the object, in order to give a more precise
5501+ result. ``__builtin_dynamic_object_size `` is meant to be used as a drop-in
5502+ replacement for ``__builtin_object_size `` in libraries that support it. For
5503+ instance, here is a program that ``__builtin_dynamic_object_size `` will make
54355504safer:
54365505
54375506.. code-block :: c
0 commit comments