-
Notifications
You must be signed in to change notification settings - Fork 253
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
analyze: introduce FlagSet::FIXED #920
Conversation
_ => None, | ||
}; | ||
if let Some(ref_pl) = ref_pl { | ||
// For simplicity, we consider taking the address of a local to be a write. We |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why is this considered a write? what does that imply downstream?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Again, just being conservative. What we're looking for here is the code that's generated by &x
/&mut x
expressions in the source, which consists of a temporary _1
that's initialized with a statement _1 = &mut ...;
and which otherwise isn't written in any way.
We might need to do something slightly smarter here in the future, if we eventually need to handle &mut &mut x
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think some or all of your response is worth adding as a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could we add some filecheck tests for this? |
Would the temporary refs analysis still be necessary if the transpiler only used |
I think the analysis wouldn't be needed in that case, but I didn't want to block these changes on that transpiler bug being fixed. |
Yeah, that makes sense. It's good to know, though, that fixing that bug would simplify these kinds of analyses as well as eliminate UB. |
I've reformulated the rules for applying FIXED: a63fca4. This should produce the same results as the previous version, but it should be easier to reason about and more consistent in its handling of complex cases. Tomorrow I'll add a filecheck test, and then I think it will be ready to merge. |
Co-authored-by: Khyber Sen <[email protected]>
a51bb14
to
8611f9e
Compare
Rebased onto |
8611f9e
to
5c9335b
Compare
Added a test case (and fixed a small bug it uncovered in the new calculation of |
|
||
for local in mir.local_decls.indices() { | ||
let is_temp_ref = mir.local_kind(local) == LocalKind::Temp | ||
&& write_count.get(&local).copied().unwrap_or(0) == 1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
am i reading this right that you're only looking for cases where an address of a local is taken and stored into a temp, where the rhs is not a reborrow?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, we don't care what Place
the temporary reference points to. _1 = &_2
, _1 = &_2.0
, and _1 = &*_2
are all treated the same for our purposes. We only care whether the LHS variable looks like it's a temporary storing the result of a source-level &...
expression.
@@ -547,6 +609,7 @@ fn run(tcx: TyCtxt) { | |||
assert!(acx.local_tys.is_empty()); | |||
acx.local_tys = IndexVec::with_capacity(mir.local_decls.len()); | |||
for (local, decl) in mir.local_decls.iter_enumerated() { | |||
// TODO: set PointerInfo::ANNOTATED for the parts of the type with user annotations |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can this even be gleaned from MIR? I thought type annotations were only visible at the HIR level
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think they're in Body::user_type_annotations (though I haven't looked into it in detail)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wasn't this going to fix rewriting bugs removing mut
from &mut A
in fields.rs
in the function it has? Why is that no longer the case?
This PR only adds code for computing the |
Adds a new flag,
FIXED
, which indicates that the pointer type must not be changed during rewriting. This branch only adds the flag and sets it on somePointerId
s where it's appropriate; nothing consumes this new flag (yet).For now, we set the
FIXED
flag on allTyKind::Ref
s in the input program. This will eventually allow us to avoid rewriting code that's already safe. However, we don't set theFIXED
flag for MIR temporaries introduced to hold the results of&x
or&mut x
expressions. This is because c2rust-transpile still uses&mut x as *mut T
instead ofaddr_of_mut!(x)
for the C address-of operator, and we sometimes need to rewrite these expressions in a way that changes their types. This also applies to cases likearray.as_mut_ptr()
, which implicitly works like(&mut array).as_mut_ptr()
.Based on #919 for now; once this is approved, I'll rebase onto
master
.