[codegen] Check for downcasting in bitcast instruction

Bitcasting to a smaller size is invalid.

closes #854
This commit is contained in:
Wander Lairson Costa
2019-09-16 18:59:23 -03:00
committed by Benjamin Bouvier
parent 5426e42a27
commit 863ac809d9
2 changed files with 52 additions and 0 deletions

View File

@@ -696,6 +696,13 @@ impl<'a> Verifier<'a> {
} }
} }
Unary {
opcode: Opcode::Bitcast,
arg,
} => {
self.verify_bitcast(inst, arg, errors)?;
}
// Exhaustive list so we can't forget to add new formats // Exhaustive list so we can't forget to add new formats
Unary { .. } Unary { .. }
| UnaryImm { .. } | UnaryImm { .. }
@@ -981,6 +988,28 @@ impl<'a> Verifier<'a> {
} }
} }
fn verify_bitcast(
&self,
inst: Inst,
arg: Value,
errors: &mut VerifierErrors,
) -> VerifierStepResult<()> {
let typ = self.func.dfg.ctrl_typevar(inst);
let value_type = self.func.dfg.value_type(arg);
if typ.lane_bits() < value_type.lane_bits() {
fatal!(
errors,
inst,
"The bitcast argument {} doesn't fit in a type of {} bits",
arg,
typ.lane_bits()
)
} else {
Ok(())
}
}
fn domtree_integrity( fn domtree_integrity(
&self, &self,
domtree: &DominatorTree, domtree: &DominatorTree,

View File

@@ -0,0 +1,23 @@
test verifier
; bitcast between two types of equal size if ok
function %valid_bitcast1(i32) -> f32 { ; Ok
ebb0(v0: i32):
v1 = bitcast.f32 v0
return v1
}
; bitcast to a type larger than the operand is ok
function %valid_bitcast2(i32) -> i64 { ; Ok
ebb0(v0: i32):
v1 = bitcast.i64 v0
return v1
}
; bitcast to a smaller type is not ok
function %bad_bitcast(i64) -> i32 {
ebb0(v0: i64):
v1 = bitcast.i32 v0 ; error: The bitcast argument v0 doesn't fit in a type of 32 bits
return v1
}