Skip to content

Commit 2f85a74

Browse files
committed
Special rule to skip alignment-checking basic block
- plus test program having this block of code which previously failed Related: #638
1 parent f8f55a5 commit 2f85a74

File tree

2 files changed

+111
-0
lines changed

2 files changed

+111
-0
lines changed

kmir/src/kmir/kdist/mir-semantics/kmir.md

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,106 @@ blocks, or call another function).
8989
</k>
9090
```
9191

92+
#### Special-Purpose Rule for alignment check sequence
93+
94+
A characteristic sequence of statements and assert terminator is generated by the compiler
95+
when performing an alignment check before a pointer is dereferenced.
96+
We optionally skip the entire block since we do not use `Int`-sorted memory addresses anyway.
97+
98+
```k
99+
rule [skip-alignment-check-block]:
100+
<k> #execStmts(
101+
statement (...
102+
kind: statementKindAssign (...
103+
place: place (... local: PTR_UNIT , projection: .ProjectionElems ) ,
104+
rvalue: rvalueCast (
105+
castKindPtrToPtr ,
106+
operandCopy ( place (... local: _PTR_ORIG , projection: .ProjectionElems ) ) ,
107+
_UNIT_PTR_TY ) ) , // cast original to *()
108+
span: SPAN )
109+
statement (...
110+
kind: statementKindAssign (...
111+
place: place (... local: ADDR , projection: .ProjectionElems ) ,
112+
rvalue: rvalueCast (
113+
castKindTransmute ,
114+
operandCopy ( place (... local: PTR_UNIT , projection: .ProjectionElems ) ) ,
115+
USIZE_TY ) ) ,
116+
span: SPAN )
117+
statement (...
118+
kind: statementKindAssign (...
119+
place: place (... local: ALIGNMENT , projection: .ProjectionElems ) ,
120+
rvalue: rvalueNullaryOp ( nullOpAlignOf , _ORIG_TY ) ) ,
121+
span: SPAN )
122+
statement (...
123+
kind: statementKindAssign (...
124+
place: place (... local: ALIGN_MASK , projection: .ProjectionElems ) ,
125+
rvalue: rvalueBinaryOp (
126+
binOpSub ,
127+
operandCopy ( place (... local: ALIGNMENT , projection: .ProjectionElems ) ) ,
128+
operandConstant ( constOperand (...
129+
span: SPAN ,
130+
userTy: noUserTypeAnnotationIndex ,
131+
const: mirConst (...
132+
kind: constantKindAllocated (
133+
allocation (...
134+
bytes: b"\x01\x00\x00\x00\x00\x00\x00\x00" ,
135+
provenance: provenanceMap (... ptrs: .ProvenanceMapEntries ) ,
136+
align: align ( 8 ) ,
137+
mutability: mutabilityMut ) ) ,
138+
ty: USIZE_TY ,
139+
id: _ ) ) ) ) ) ,
140+
span: SPAN )
141+
statement (...
142+
kind: statementKindAssign (...
143+
place: place (... local: MASKED , projection: .ProjectionElems ) ,
144+
rvalue: rvalueBinaryOp (
145+
binOpBitAnd ,
146+
operandCopy ( place (... local: ADDR , projection: .ProjectionElems ) ) ,
147+
operandCopy ( place (... local: ALIGN_MASK , projection: .ProjectionElems ) ) ) ) ,
148+
span: SPAN )
149+
statement (...
150+
kind: statementKindAssign (...
151+
place: place (...
152+
local: RESULT , projection: .ProjectionElems ) ,
153+
rvalue: rvalueBinaryOp (
154+
binOpEq ,
155+
operandCopy ( place (... local: MASKED , projection: .ProjectionElems ) ) ,
156+
operandConstant ( constOperand (...
157+
span: SPAN ,
158+
userTy: noUserTypeAnnotationIndex ,
159+
const: mirConst (...
160+
kind: constantKindAllocated (
161+
allocation (...
162+
bytes: b"\x00\x00\x00\x00\x00\x00\x00\x00" ,
163+
provenance: provenanceMap (... ptrs: .ProvenanceMapEntries ) ,
164+
align: align ( 8 ) ,
165+
mutability: mutabilityMut ) ) ,
166+
ty: USIZE_TY ,
167+
id: _ ) ) ) ) ) ,
168+
span: SPAN )
169+
.Statements
170+
)
171+
~> #execTerminator(
172+
terminator (...
173+
kind: assert (...
174+
cond: operandCopy ( place (... local: RESULT , projection: .ProjectionElems ) ) ,
175+
expected: true ,
176+
msg: assertMessageMisalignedPointerDereference (...
177+
required: operandCopy ( place (... local: ALIGNMENT , projection: .ProjectionElems ) ) ,
178+
found: operandCopy ( place (... local: ADDR , projection: .ProjectionElems ) )
179+
) ,
180+
target: TARGET,
181+
unwind: unwindActionUnreachable
182+
) ,
183+
span: SPAN
184+
)
185+
)
186+
~> .K
187+
=> #execBlockIdx(TARGET)
188+
</k>
189+
[priority(40), preserves-definedness]
190+
```
191+
92192
`Statement` execution handles the different `StatementKind`s. Some of
93193
these are irrelevant at the MIR level that this semantics is modeling
94194
(e.g., all statements related to compile-time checks like borrowing
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
struct Thing {payload: i16}
2+
3+
fn main() {
4+
5+
let a = [Thing{payload: 1}, Thing{payload: 2}, Thing{payload:3}];
6+
let p = &a as *const Thing;
7+
let p1 = unsafe { p.add(1) };
8+
9+
let two = unsafe { (*p1).payload };
10+
assert!(two == 2);
11+
}

0 commit comments

Comments
 (0)