-
Notifications
You must be signed in to change notification settings - Fork 97
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
Investigate why mir-linker test requires an unwind annotation #1978
Comments
It seems that we end up with a comparison to two constant-to-pointer type casts, where one of the constants (because of how we now do simplification) ends up have a different (but still perfectly correct) bitvector type. This fools a subsequent equality test. I'm trying to figure out how to make the equality test sufficiently smart. |
This is to make sure that we can simplify equality tests over pointer-typed expressions where at least one of them was created via a sequence of simplification steps. Seen in model-checking/kani#1978, but the new simplification code is actually triggered by mm_io1, r_w_ok10, and union12 regression tests.
Fixed in diffblue/cbmc#7427. |
On a second thought I have decided to discard the proposed change to CBMC. Instead, I started wondering where those pointer-typed constants with non-NULL value are coming from. It turns out Kani directly emitted that. From the symtab:
which in turn is the result of translating |
Interesting. I expect the Rust compiler to try to maintain providence reasonably well, so I'm not (without digging in) where this is coming from. It could easily be mistranslation in Kani. I understand that in C you'd only ever get a pointer constant by writing an integer and casting it to a pointer type. Am I understanding you correctly that this is what you'd want for goto as well? If so, I think the validation should reject a raw pointer constant. |
We obviously lack a formalisation of GOTO programs at this point, but I'm not sure what semantics to attribute to a pointer-typed constant in the (not formalised) memory model of GOTO programs. The null-pointer constant we store as having a value of "NULL" (not zero!). The only other pointer-typed expression that I'd consider a legitimate constant is taking the address of an object. |
Nominating this as high priority, since it might be a translation bug, and it should be simple to figure out (by asserting about types in the right constructor in our bindings) |
Generating a pointer-typed numeric constant can be reproduced on this small program:
Symbol table:
Specifically these lines in the comment:
|
This diff eliminates the pointer constant from the symbol table file generated by Kani: $ git diff
diff --git a/kani-compiler/src/codegen_cprover_gotoc/codegen/operand.rs b/kani-compiler/src/codegen_cprover_gotoc/codegen/operand.rs
index 7756bc95229..0bc4a56fca9 100644
--- a/kani-compiler/src/codegen_cprover_gotoc/codegen/operand.rs
+++ b/kani-compiler/src/codegen_cprover_gotoc/codegen/operand.rs
@@ -284,7 +284,8 @@ fn codegen_scalar(&mut self, s: Scalar, ty: Ty<'tcx>, span: Option<&Span>) -> Ex
unreachable!("ZST is no longer represented as a scalar")
}
(Scalar::Int(_), ty::RawPtr(tm)) => {
- Expr::pointer_constant(s.to_u64().unwrap(), self.codegen_ty(tm.ty).to_pointer())
+ Expr::int_constant(s.to_u64().unwrap(), Type::unsigned_int(64))
+ .cast_to(self.codegen_ty(tm.ty).to_pointer())
} The resulting symbol table for the mir-linker test becomes:
The change passes regressions, but it does not eliminate the need to specify an unwind value. Not sure if I should create a PR for it. @tautschnig? |
Adding this back onto my list. I'll try to see which additional changes might be necessary on the CBMC side. |
Thanks @tautschnig. And do you think it's still worthwhile to open a PR to switch to using a pointer cast for pointer constants? |
In 848e633 a cast to bv was inserted to block interpreting floatbv type casts from taking place. It was unnecessarily inserted for all bitvector types. While this does not result in wrong semantics, it may block simplification for happening when we end up (via other simplifier rules) creating a bv (and not (un)signed bv) typed constant. All of these transformations are correct, but we may end up with an equality over pointer-typed constants where the underlying constant is a(n) (un)signed bv on one side, and a bv on the other side. The bit patterns match, so the back-end will correctly solve this, but the simplifier cannot. Observed when studying model-checking/kani#1978.
With apologies for taking this long to get back to this: yes, we do still want this fix to be merged. It might, however, be a good idea to combine it with a change to the test that drops the unwind annotation. That you can drop once diffblue/cbmc#7571 is merged into CBMC and the above fix to use pointer casts is applied. |
In 848e633 a cast to bv was inserted to block interpreting floatbv type casts from taking place. It was unnecessarily inserted for all bitvector types. While this does not result in wrong semantics, it may block simplification for happening when we end up (via other simplifier rules) creating a bv (and not (un)signed bv) typed constant. All of these transformations are correct, but we may end up with an equality over pointer-typed constants where the underlying constant is a(n) (un)signed bv on one side, and a bv on the other side. The bit patterns match, so the back-end will correctly solve this, but the simplifier cannot. Observed when studying model-checking/kani#1978.
In 848e633 a cast to bv was inserted to block interpreting floatbv type casts from taking place. It was unnecessarily inserted for all bitvector types. While this does not result in wrong semantics, it may block simplification for happening when we end up (via other simplifier rules) creating a bv (and not (un)signed bv) typed constant. All of these transformations are correct, but we may end up with an equality over pointer-typed constants where the underlying constant is a(n) (un)signed bv on one side, and a bv on the other side. The bit patterns match, so the back-end will correctly solve this, but the simplifier cannot. Observed when studying model-checking/kani#1978.
- Re-enable tests that had to be disabled with the toolchain upgrade in model-checking#2149. Fixes model-checking#2286, fixes model-checking#2191. - Do not generate non-NULL pointer constants. Together with the CBMC version update this avoids the need for an unwinding annotation in the mir-linker test. Fixes model-checking#1978. - CBMC 5.79.0 ships simplifier improvements that enable constant propagation to avoid slow-down with the Display trait. Fixes model-checking#1996. - CBMC 5.79.0 ships SMT back-end fixes. Fixes model-checking#2002. Co-authored-by: Zyad Hassan <[email protected]>
This is concerned with the mir-linker test (
tests/cargo-kani/mir-linker/src/lib.rs
).Before CBMC 5.72.0, this test did not require an unwind annotation.
With CBMC 5.72.0, not specifying an unwind value causes it to unwind forever (see #1941).
Investigate why.
The text was updated successfully, but these errors were encountered: