@@ -5422,16 +5422,85 @@ The ``#pragma comment(lib, ...)`` directive is supported on all ELF targets.
5422
5422
The second parameter is the library name (without the traditional Unix prefix of
5423
5423
``lib ``). This allows you to provide an implicit link of dependent libraries.
5424
5424
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.
5427
5446
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
5433
5472
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
5435
5504
safer:
5436
5505
5437
5506
.. code-block :: c
0 commit comments