@@ -1397,6 +1397,42 @@ Currently, only the following parameter attributes are defined:
1397
1397
function, returning a pointer to allocated storage disjoint from the
1398
1398
storage for any other object accessible to the caller.
1399
1399
1400
+ ``captures(...)``
1401
+ This attributes restrict the ways in which the callee may capture the
1402
+ pointer. This is not a valid attribute for return values. This attribute
1403
+ applies only to the particular copy of the pointer passed in this argument.
1404
+
1405
+ The arguments of ``captures`` is a list of captured pointer components,
1406
+ which may be ``none``, or a combination of:
1407
+
1408
+ - ``address``: The integral address of the pointer.
1409
+ - ``address_is_null`` (subset of ``address``): Whether the address is null.
1410
+ - ``provenance``: The ability to access the pointer for both read and write
1411
+ after the function returns.
1412
+ - ``read_provenance`` (subset of ``provenance``): The ability to access the
1413
+ pointer only for reads after the function returns.
1414
+
1415
+ Additionally, it is possible to specify that some components are only
1416
+ captured in certain locations. Currently only the return value (``ret``)
1417
+ and other (default) locations are supported.
1418
+
1419
+ The `pointer capture section <pointercapture>` discusses these semantics
1420
+ in more detail.
1421
+
1422
+ Some examples of how to use the attribute:
1423
+
1424
+ - ``captures(none)``: Pointer not captured.
1425
+ - ``captures(address, provenance)``: Equivalent to omitting the attribute.
1426
+ - ``captures(address)``: Address may be captured, but not provenance.
1427
+ - ``captures(address_is_null)``: Only captures whether the address is null.
1428
+ - ``captures(address, read_provenance)``: Both address and provenance
1429
+ captured, but only for read-only access.
1430
+ - ``captures(ret: address, provenance)``: Pointer captured through return
1431
+ value only.
1432
+ - ``captures(address_is_null, ret: address, provenance)``: The whole pointer
1433
+ is captured through the return value, and additionally whether the pointer
1434
+ is null is captured in some other way.
1435
+
1400
1436
.. _nocapture:
1401
1437
1402
1438
``nocapture``
@@ -3339,10 +3375,92 @@ Pointer Capture
3339
3375
---------------
3340
3376
3341
3377
Given a function call and a pointer that is passed as an argument or stored in
3342
- the memory before the call, a pointer is *captured* by the call if it makes a
3343
- copy of any part of the pointer that outlives the call.
3344
- To be precise, a pointer is captured if one or more of the following conditions
3345
- hold:
3378
+ memory before the call, the call may capture two components of the pointer:
3379
+
3380
+ * The address of the pointer, which is its integral value. This also includes
3381
+ parts of the address or any information about the address, including the
3382
+ fact that it does not equal one specific value. We further distinguish
3383
+ whether only the fact that the address is/isn't null is captured.
3384
+ * The provenance of the pointer, which is the ability to perform memory
3385
+ accesses through the pointer, in the sense of the :ref:`pointer aliasing
3386
+ rules <pointeraliasing>`. We further distinguish whether only read acceses
3387
+ are allowed, or both reads and writes.
3388
+
3389
+ For example, the following function captures the address of ``%a``, because
3390
+ it is compared to a pointer, leaking information about the identitiy of the
3391
+ pointer:
3392
+
3393
+ .. code-block:: llvm
3394
+
3395
+ @glb = global i8 0
3396
+
3397
+ define i1 @f(ptr %a) {
3398
+ %c = icmp eq ptr %a, @glb
3399
+ ret i1 %c
3400
+ }
3401
+
3402
+ The function does not capture the provenance of the pointer, because the
3403
+ ``icmp`` instruction only operates on the pointer address. The following
3404
+ function captures both the address and provenance of the pointer, as both
3405
+ may be read from ``@glb`` after the function returns:
3406
+
3407
+ .. code-block:: llvm
3408
+
3409
+ @glb = global ptr null
3410
+
3411
+ define void @f(ptr %a) {
3412
+ store ptr %a, ptr @glb
3413
+ ret void
3414
+ }
3415
+
3416
+ The following function captures *neither* the address nor the provenance of
3417
+ the pointer:
3418
+
3419
+ .. code-block:: llvm
3420
+
3421
+ define i32 @f(ptr %a) {
3422
+ %v = load i32, ptr %a
3423
+ ret i32
3424
+ }
3425
+
3426
+ While address capture includes uses of the address within the body of the
3427
+ function, provenance capture refers exclusively to the ability to perform
3428
+ accesses *after* the function returns. Memory accesses within the function
3429
+ itself are not considered pointer captures.
3430
+
3431
+ We can further say that the capture only occurs through a specific location.
3432
+ In the following example, the pointer (both address and provenance) is captured
3433
+ through the return value only:
3434
+
3435
+ .. code-block:: llvm
3436
+
3437
+ define ptr @f(ptr %a) {
3438
+ %gep = getelementptr i8, ptr %a, i64 4
3439
+ ret ptr %gep
3440
+ }
3441
+
3442
+ However, we always consider direct inspection of the pointer address
3443
+ (e.g. using ``ptrtoint``) to be location-independent. The following example
3444
+ is *not* considered a return-only capture, even though the ``ptrtoint``
3445
+ ultimately only contribues to the return value:
3446
+
3447
+ .. code-block:: llvm
3448
+
3449
+ @lookup = constant [4 x i8] [i8 0, i8 1, i8 2, i8 3]
3450
+
3451
+ define ptr @f(ptr %a) {
3452
+ %a.addr = ptrtoint ptr %a to i64
3453
+ %mask = and i64 %a.addr, 3
3454
+ %gep = getelementptr i8, ptr @lookup, i64 %mask
3455
+ ret ptr %gep
3456
+ }
3457
+
3458
+ This definition is chosen to allow capture analysis to continue with the return
3459
+ value in the usual fashion.
3460
+
3461
+ The following describes possible ways to capture a pointer in more detail,
3462
+ where unqualified uses of the word "capture" refer to capturing both address
3463
+ and provenance.
3346
3464
3347
3465
1. The call stores any bit of the pointer carrying information into a place,
3348
3466
and the stored bits can be read from the place by the caller after this call
@@ -3381,30 +3499,30 @@ hold:
3381
3499
@lock = global i1 true
3382
3500
3383
3501
define void @f(ptr %a) {
3384
- store ptr %a, ptr* @glb
3502
+ store ptr %a, ptr @glb
3385
3503
store atomic i1 false, ptr @lock release ; %a is captured because another thread can safely read @glb
3386
3504
store ptr null, ptr @glb
3387
3505
ret void
3388
3506
}
3389
3507
3390
- 3. The call's behavior depends on any bit of the pointer carrying information.
3508
+ 3. The call's behavior depends on any bit of the pointer carrying information
3509
+ (address capture only).
3391
3510
3392
3511
.. code-block:: llvm
3393
3512
3394
3513
@glb = global i8 0
3395
3514
3396
3515
define void @f(ptr %a) {
3397
3516
%c = icmp eq ptr %a, @glb
3398
- br i1 %c, label %BB_EXIT, label %BB_CONTINUE ; escapes %a
3517
+ br i1 %c, label %BB_EXIT, label %BB_CONTINUE ; captures address of %a only
3399
3518
BB_EXIT:
3400
3519
call void @exit()
3401
3520
unreachable
3402
3521
BB_CONTINUE:
3403
3522
ret void
3404
3523
}
3405
3524
3406
- 4. The pointer is used in a volatile access as its address.
3407
-
3525
+ 4. The pointer is used as the pointer operand of a volatile access.
3408
3526
3409
3527
.. _volatile:
3410
3528
0 commit comments