-
Notifications
You must be signed in to change notification settings - Fork 4
fix(rt): align transparent pointer casts #811
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
Changes from all commits
16daa94
2596f5a
3083f4b
0f93087
fdb314c
2f30c37
d55c2e7
b7eac02
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| struct Wrapper(u32); | ||
|
|
||
| fn roundtrip(ptr: *const Wrapper) -> u32 { | ||
| unsafe { | ||
| let erased = ptr as *const (); | ||
| let restored = erased as *const Wrapper; | ||
| (*restored).0 | ||
| } | ||
| } | ||
|
|
||
| fn main() { | ||
| let value = Wrapper(0xCAFE_BABE); | ||
| assert!(roundtrip(&value) == 0xCAFE_BABE); | ||
| } |
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,50 @@ | ||
| <kmir> | ||
| <k> | ||
| PtrLocal ( 1 , place (... local: local ( 1 ) , projection: projectionElemField ( fieldIdx ( 0 ) , ty ( 29 ) ) .ProjectionElems ) , mutabilityNot , metadata ( noMetadataSize , 0 , noMetadataSize ) ) ~> #freezer#setLocalValue(_,_)_RT-DATA_KItem_Place_Evaluation1_ ( place (... local: local ( 2 ) , projection: .ProjectionElems ) ~> .K ) ~> #execStmts ( statement (... kind: statementKindAssign (... place: place (... local: local ( 3 ) , projection: .ProjectionElems ) , rvalue: rvalueCast ( castKindPtrToPtr , operandCopy ( place (... local: local ( 2 ) , projection: .ProjectionElems ) ) , ty ( 26 ) ) ) , span: span ( 52 ) ) statement (... kind: statementKindAssign (... place: place (... local: local ( 4 ) , projection: .ProjectionElems ) , rvalue: rvalueCast ( castKindPtrToPtr , operandCopy ( place (... local: local ( 3 ) , projection: .ProjectionElems ) ) , ty ( 25 ) ) ) , span: span ( 50 ) ) statement (... kind: statementKindAssign (... place: place (... local: local ( 5 ) , projection: .ProjectionElems ) , rvalue: rvalueCast ( castKindTransmute , operandCopy ( place (... local: local ( 4 ) , projection: .ProjectionElems ) ) , ty ( 27 ) ) ) , span: span ( 50 ) ) statement (... kind: statementKindAssign (... place: place (... local: local ( 6 ) , projection: .ProjectionElems ) , rvalue: rvalueNullaryOp ( nullOpAlignOf , ty ( 28 ) ) ) , span: span ( 50 ) ) statement (... kind: statementKindAssign (... place: place (... local: local ( 7 ) , projection: .ProjectionElems ) , rvalue: rvalueBinaryOp ( binOpSub , operandCopy ( place (... local: local ( 6 ) , projection: .ProjectionElems ) ) , operandConstant ( constOperand (... span: span ( 50 ) , userTy: noUserTypeAnnotationIndex , const: mirConst (... kind: constantKindAllocated ( allocation (... bytes: b"\x01\x00\x00\x00\x00\x00\x00\x00" , provenance: provenanceMap (... ptrs: .ProvenanceMapEntries ) , align: align ( 8 ) , mutability: mutabilityMut ) ) , ty: ty ( 27 ) , id: mirConstId ( 9 ) ) ) ) ) ) , span: span ( 50 ) ) statement (... kind: statementKindAssign (... place: place (... local: local ( 8 ) , projection: .ProjectionElems ) , rvalue: rvalueBinaryOp ( binOpBitAnd , operandCopy ( place (... local: local ( 5 ) , projection: .ProjectionElems ) ) , operandCopy ( place (... local: local ( 7 ) , projection: .ProjectionElems ) ) ) ) , span: span ( 50 ) ) statement (... kind: statementKindAssign (... place: place (... local: local ( 9 ) , projection: .ProjectionElems ) , rvalue: rvalueBinaryOp ( binOpEq , operandCopy ( place (... local: local ( 8 ) , projection: .ProjectionElems ) ) , operandConstant ( constOperand (... span: span ( 50 ) , userTy: noUserTypeAnnotationIndex , const: mirConst (... kind: constantKindAllocated ( allocation (... bytes: b"\x00\x00\x00\x00\x00\x00\x00\x00" , provenance: provenanceMap (... ptrs: .ProvenanceMapEntries ) , align: align ( 8 ) , mutability: mutabilityMut ) ) , ty: ty ( 27 ) , id: mirConstId ( 10 ) ) ) ) ) ) , span: span ( 50 ) ) .Statements ) ~> #execTerminator ( terminator (... kind: assert (... cond: operandCopy ( place (... local: local ( 9 ) , projection: .ProjectionElems ) ) , expected: true , msg: assertMessageMisalignedPointerDereference (... required: operandCopy ( place (... local: local ( 6 ) , projection: .ProjectionElems ) ) , found: operandCopy ( place (... local: local ( 5 ) , projection: .ProjectionElems ) ) ) , target: basicBlockIdx ( 1 ) , unwind: unwindActionUnreachable ) , span: span ( 50 ) ) ) ~> .K | ||
| </k> | ||
| <retVal> | ||
| noReturn | ||
| </retVal> | ||
| <currentFunc> | ||
| ty ( 31 ) | ||
| </currentFunc> | ||
| <currentFrame> | ||
| <currentBody> | ||
| ListItem ( basicBlock (... statements: statement (... kind: statementKindAssign (... place: place (... local: local ( 2 ) , projection: .ProjectionElems ) , rvalue: rvalueCast ( castKindPtrToPtr , operandCopy ( place (... local: local ( 1 ) , projection: .ProjectionElems ) ) , ty ( 25 ) ) ) , span: span ( 51 ) ) statement (... kind: statementKindAssign (... place: place (... local: local ( 3 ) , projection: .ProjectionElems ) , rvalue: rvalueCast ( castKindPtrToPtr , operandCopy ( place (... local: local ( 2 ) , projection: .ProjectionElems ) ) , ty ( 26 ) ) ) , span: span ( 52 ) ) statement (... kind: statementKindAssign (... place: place (... local: local ( 4 ) , projection: .ProjectionElems ) , rvalue: rvalueCast ( castKindPtrToPtr , operandCopy ( place (... local: local ( 3 ) , projection: .ProjectionElems ) ) , ty ( 25 ) ) ) , span: span ( 50 ) ) statement (... kind: statementKindAssign (... place: place (... local: local ( 5 ) , projection: .ProjectionElems ) , rvalue: rvalueCast ( castKindTransmute , operandCopy ( place (... local: local ( 4 ) , projection: .ProjectionElems ) ) , ty ( 27 ) ) ) , span: span ( 50 ) ) statement (... kind: statementKindAssign (... place: place (... local: local ( 6 ) , projection: .ProjectionElems ) , rvalue: rvalueNullaryOp ( nullOpAlignOf , ty ( 28 ) ) ) , span: span ( 50 ) ) statement (... kind: statementKindAssign (... place: place (... local: local ( 7 ) , projection: .ProjectionElems ) , rvalue: rvalueBinaryOp ( binOpSub , operandCopy ( place (... local: local ( 6 ) , projection: .ProjectionElems ) ) , operandConstant ( constOperand (... span: span ( 50 ) , userTy: noUserTypeAnnotationIndex , const: mirConst (... kind: constantKindAllocated ( allocation (... bytes: b"\x01\x00\x00\x00\x00\x00\x00\x00" , provenance: provenanceMap (... ptrs: .ProvenanceMapEntries ) , align: align ( 8 ) , mutability: mutabilityMut ) ) , ty: ty ( 27 ) , id: mirConstId ( 9 ) ) ) ) ) ) , span: span ( 50 ) ) statement (... kind: statementKindAssign (... place: place (... local: local ( 8 ) , projection: .ProjectionElems ) , rvalue: rvalueBinaryOp ( binOpBitAnd , operandCopy ( place (... local: local ( 5 ) , projection: .ProjectionElems ) ) , operandCopy ( place (... local: local ( 7 ) , projection: .ProjectionElems ) ) ) ) , span: span ( 50 ) ) statement (... kind: statementKindAssign (... place: place (... local: local ( 9 ) , projection: .ProjectionElems ) , rvalue: rvalueBinaryOp ( binOpEq , operandCopy ( place (... local: local ( 8 ) , projection: .ProjectionElems ) ) , operandConstant ( constOperand (... span: span ( 50 ) , userTy: noUserTypeAnnotationIndex , const: mirConst (... kind: constantKindAllocated ( allocation (... bytes: b"\x00\x00\x00\x00\x00\x00\x00\x00" , provenance: provenanceMap (... ptrs: .ProvenanceMapEntries ) , align: align ( 8 ) , mutability: mutabilityMut ) ) , ty: ty ( 27 ) , id: mirConstId ( 10 ) ) ) ) ) ) , span: span ( 50 ) ) .Statements , terminator: terminator (... kind: assert (... cond: operandCopy ( place (... local: local ( 9 ) , projection: .ProjectionElems ) ) , expected: true , msg: assertMessageMisalignedPointerDereference (... required: operandCopy ( place (... local: local ( 6 ) , projection: .ProjectionElems ) ) , found: operandCopy ( place (... local: local ( 5 ) , projection: .ProjectionElems ) ) ) , target: basicBlockIdx ( 1 ) , unwind: unwindActionUnreachable ) , span: span ( 50 ) ) ) ) | ||
| ListItem ( basicBlock (... statements: statement (... kind: statementKindAssign (... place: place (... local: local ( 0 ) , projection: .ProjectionElems ) , rvalue: rvalueUse ( operandCopy ( place (... local: local ( 3 ) , projection: projectionElemDeref projectionElemField ( fieldIdx ( 0 ) , ty ( 29 ) ) .ProjectionElems ) ) ) ) , span: span ( 50 ) ) .Statements , terminator: terminator (... kind: terminatorKindReturn , span: span ( 53 ) ) ) ) | ||
| </currentBody> | ||
| <caller> | ||
| ty ( -1 ) | ||
| </caller> | ||
| <dest> | ||
| place (... local: local ( 2 ) , projection: .ProjectionElems ) | ||
| </dest> | ||
| <target> | ||
| someBasicBlockIdx ( basicBlockIdx ( 1 ) ) | ||
| </target> | ||
| <unwind> | ||
| unwindActionContinue | ||
| </unwind> | ||
| <locals> | ||
| ListItem ( newLocal ( ty ( 29 ) , mutabilityMut ) ) | ||
| ListItem ( typedValue ( PtrLocal ( 1 , place (... local: local ( 1 ) , projection: .ProjectionElems ) , mutabilityNot , metadata ( noMetadataSize , 0 , noMetadataSize ) ) , ty ( 26 ) , mutabilityNot ) ) | ||
| ListItem ( newLocal ( ty ( 25 ) , mutabilityNot ) ) | ||
| ListItem ( newLocal ( ty ( 26 ) , mutabilityNot ) ) | ||
| ListItem ( newLocal ( ty ( 25 ) , mutabilityMut ) ) | ||
| ListItem ( newLocal ( ty ( 27 ) , mutabilityMut ) ) | ||
| ListItem ( newLocal ( ty ( 27 ) , mutabilityMut ) ) | ||
| ListItem ( newLocal ( ty ( 27 ) , mutabilityMut ) ) | ||
| ListItem ( newLocal ( ty ( 27 ) , mutabilityMut ) ) | ||
| ListItem ( newLocal ( ty ( 30 ) , mutabilityMut ) ) | ||
| </locals> | ||
| </currentFrame> | ||
| <stack> | ||
| ListItem ( StackFrame ( ty ( -1 ) , place (... local: local ( 0 ) , projection: .ProjectionElems ) , noBasicBlockIdx , unwindActionContinue , ListItem ( newLocal ( ty ( 1 ) , mutabilityMut ) ) | ||
| ListItem ( typedValue ( Aggregate ( variantIdx ( 0 ) , ListItem ( Integer ( 3405691582 , 32 , false ) ) ) , ty ( 28 ) , mutabilityNot ) ) | ||
| ListItem ( newLocal ( ty ( 29 ) , mutabilityMut ) ) | ||
| ListItem ( typedValue ( Moved , ty ( 26 ) , mutabilityMut ) ) | ||
| ListItem ( typedValue ( Reference ( 0 , place (... local: local ( 1 ) , projection: .ProjectionElems ) , mutabilityNot , metadata ( noMetadataSize , 0 , noMetadataSize ) ) , ty ( 34 ) , mutabilityNot ) ) | ||
| ListItem ( newLocal ( ty ( 35 ) , mutabilityMut ) ) ) ) | ||
| ListItem ( StackFrame ( ty ( -1 ) , place (... local: local ( -1 ) , projection: .ProjectionElems ) , noBasicBlockIdx , unwindActionUnreachable , .List ) ) | ||
| </stack> | ||
| </kmir> |
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -26,11 +26,34 @@ | |
| │ #execBlockIdx ( basicBlockIdx ( 8 ) ) ~> .K | ||
| │ function: main | ||
| │ | ||
| │ (8 steps) | ||
| └─ 7 (stuck, leaf) | ||
| #traverseProjection ( toLocal ( 2 ) , thunk ( #cast ( PtrLocal ( 1 , place ( ... | ||
| function: main | ||
| span: 80 | ||
| │ (111 steps) | ||
| ├─ 7 | ||
| │ #expect ( thunk ( #applyBinOp ( binOpEq , thunk ( #applyBinOp ( binOpBitAnd , th | ||
| │ function: main | ||
| ┃ | ||
| ┃ (1 step) | ||
| ┣━━┓ | ||
| ┃ │ | ||
| ┃ ├─ 8 | ||
| ┃ │ AssertError ( assertMessageMisalignedPointerDereference ( ... required: operandC | ||
| ┃ │ function: main | ||
| ┃ │ | ||
| ┃ │ (1 step) | ||
| ┃ └─ 10 (stuck, leaf) | ||
| ┃ #ProgramError ( AssertError ( assertMessageMisalignedPointerDereference ( ... re | ||
| ┃ function: main | ||
| ┃ | ||
| ┗━━┓ | ||
| │ | ||
| ├─ 9 | ||
| │ #execBlockIdx ( basicBlockIdx ( 7 ) ) ~> .K | ||
| │ function: main | ||
| │ | ||
| │ (17 steps) | ||
| └─ 11 (stuck, leaf) | ||
| #setLocalValue ( place ( ... local: local ( 1 ) , projection: .ProjectionElems ) | ||
| function: main | ||
|
Comment on lines
+29
to
+55
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. FYI This now hits a non-deterministic branch on what looks like a pointer alignment check .
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @jberthold I saw this last night in a previous proof, it comes when the pointer cast is thunked, and then the pointer is branches. I am worried it is happening because it needs to get the address but I haven't looked with details yet. If it needs the address I am not sure what we do
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think I solved it before in the big pr. Could I introduce an issue for this and solve it later in another pr?
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, we can solve this one later, it should not block this PR |
||
| span: 79 | ||
|
|
||
|
|
||
| ┌─ 2 (root, leaf, target, terminal) | ||
|
|
||
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.
A bit puzzled by the
orBoolhere... I would accept it immediately withandBool(one zero-sized thing is as good as another) but what happens if we cast a pointer to non-zero-sized to a zero-sized one and back, should that be allowed? Or which side is not allowed? (zero to non-zero I would guess)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'm investigating this with a new test, but it encounters other ndbranches.
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.
It needs a cast from pointer to integer. here: #812
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 provided
pointer-cast-zst.rsto cover this scenario: it casts a*const Wrapperto*const ()(ZST) and back, then asserts the roundtrip preserves the value. Since this test passes, the semantics currently allow non‑zero → zero → non‑zero pointer casts, so we shoud use thisorBoolto allow this situation.