let p: *mut S = ...;
let q: *mut i32 = &mut (*p).field;
Currently, we produce two PointerIds, one on p and one on q. The rvalue &mut (*p).field has the same PointerId as p, on the assumption that it must always have the same permissions as p itself.
In the pointee analysis, p and &mut (*p).field will usually have different pointee sets ({S} and {i32} respectively). But we'd like to use PointerIds to identify pointers in the pointee analysis, rather than inventing a whole new labeling system. This requires that p and &mut (*p).field have different PointerIds (though in the dataflow analysis, we will add a constraint relating their permissions, so that analysis will still produce identical results).
Actually adding PointerIds for the necessary rvalues is fairly trivial (see b57fa642c94c05381efaa81ea9123735ae18ba58). The majority of this PR consists of rewriter improvements to let it handle the new PointerIds. In particular, it can now apply rewrites to MIR code arising from expr adjustments. For example:
let arr: [u8; 3] = [0; 3];
let p: *const u8 = arr.as_ptr();
MIR line 1 is the initialization of arr. Line 2 applies a borrow adjustment to arr, line 3 applies an unsizing adjustment, and line 4 actually calls as_ptr. The MIR code produced is as if the programmer had written (&arr as &[u8]).as_ptr() rather than arr.as_ptr(). Previously, if the rewrite::expr::mir_op module tried to introduce rewrites on lines 2 or 3, it would result in an error; with this PR, those rewrites are correctly lifted to HIR (after materializing the adjustments so there is a place in the source code to apply those rewrites).
Given code like this:
Currently, we produce two
PointerId
s, one onp
and one onq
. The rvalue&mut (*p).field
has the samePointerId
asp
, on the assumption that it must always have the same permissions asp
itself.In the pointee analysis,
p
and&mut (*p).field
will usually have different pointee sets ({S}
and{i32}
respectively). But we'd like to usePointerId
s to identify pointers in the pointee analysis, rather than inventing a whole new labeling system. This requires thatp
and&mut (*p).field
have differentPointerId
s (though in the dataflow analysis, we will add a constraint relating their permissions, so that analysis will still produce identical results).Actually adding
PointerId
s for the necessary rvalues is fairly trivial (see b57fa642c94c05381efaa81ea9123735ae18ba58). The majority of this PR consists of rewriter improvements to let it handle the newPointerId
s. In particular, it can now apply rewrites to MIR code arising from expr adjustments. For example:This produces the following MIR:
MIR line 1 is the initialization of
arr
. Line 2 applies a borrow adjustment toarr
, line 3 applies an unsizing adjustment, and line 4 actually callsas_ptr
. The MIR code produced is as if the programmer had written(&arr as &[u8]).as_ptr()
rather thanarr.as_ptr()
. Previously, if therewrite::expr::mir_op
module tried to introduce rewrites on lines 2 or 3, it would result in an error; with this PR, those rewrites are correctly lifted to HIR (after materializing the adjustments so there is a place in the source code to apply those rewrites).