Fixes #738: Check ebbs used in jump tables in the verifier;
This commit is contained in:
@@ -459,6 +459,15 @@ impl<'a> Verifier<'a> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn verify_jump_tables(&self, errors: &mut VerifierErrors) -> VerifierStepResult<()> {
|
||||||
|
for (jt, jt_data) in &self.func.jump_tables {
|
||||||
|
for &ebb in jt_data.iter() {
|
||||||
|
self.verify_ebb(jt, ebb, errors)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
fn ebb_integrity(
|
fn ebb_integrity(
|
||||||
&self,
|
&self,
|
||||||
ebb: Ebb,
|
ebb: Ebb,
|
||||||
@@ -606,8 +615,13 @@ impl<'a> Verifier<'a> {
|
|||||||
self.verify_ebb(inst, destination, errors)?;
|
self.verify_ebb(inst, destination, errors)?;
|
||||||
self.verify_value_list(inst, args, errors)?;
|
self.verify_value_list(inst, args, errors)?;
|
||||||
}
|
}
|
||||||
BranchTable { table, .. }
|
BranchTable {
|
||||||
| BranchTableBase { table, .. }
|
table, destination, ..
|
||||||
|
} => {
|
||||||
|
self.verify_ebb(inst, destination, errors)?;
|
||||||
|
self.verify_jump_table(inst, table, errors)?;
|
||||||
|
}
|
||||||
|
BranchTableBase { table, .. }
|
||||||
| BranchTableEntry { table, .. }
|
| BranchTableEntry { table, .. }
|
||||||
| IndirectJump { table, .. } => {
|
| IndirectJump { table, .. } => {
|
||||||
self.verify_jump_table(inst, table, errors)?;
|
self.verify_jump_table(inst, table, errors)?;
|
||||||
@@ -685,16 +699,16 @@ impl<'a> Verifier<'a> {
|
|||||||
|
|
||||||
fn verify_ebb(
|
fn verify_ebb(
|
||||||
&self,
|
&self,
|
||||||
inst: Inst,
|
loc: impl Into<AnyEntity>,
|
||||||
e: Ebb,
|
e: Ebb,
|
||||||
errors: &mut VerifierErrors,
|
errors: &mut VerifierErrors,
|
||||||
) -> VerifierStepResult<()> {
|
) -> VerifierStepResult<()> {
|
||||||
if !self.func.dfg.ebb_is_valid(e) || !self.func.layout.is_ebb_inserted(e) {
|
if !self.func.dfg.ebb_is_valid(e) || !self.func.layout.is_ebb_inserted(e) {
|
||||||
return fatal!(errors, inst, "invalid ebb reference {}", e);
|
return fatal!(errors, loc, "invalid ebb reference {}", e);
|
||||||
}
|
}
|
||||||
if let Some(entry_block) = self.func.layout.entry_block() {
|
if let Some(entry_block) = self.func.layout.entry_block() {
|
||||||
if e == entry_block {
|
if e == entry_block {
|
||||||
return fatal!(errors, inst, "invalid reference to entry ebb {}", e);
|
return fatal!(errors, loc, "invalid reference to entry ebb {}", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -1679,6 +1693,7 @@ impl<'a> Verifier<'a> {
|
|||||||
self.verify_global_values(errors)?;
|
self.verify_global_values(errors)?;
|
||||||
self.verify_heaps(errors)?;
|
self.verify_heaps(errors)?;
|
||||||
self.verify_tables(errors)?;
|
self.verify_tables(errors)?;
|
||||||
|
self.verify_jump_tables(errors)?;
|
||||||
self.typecheck_entry_block_params(errors)?;
|
self.typecheck_entry_block_params(errors)?;
|
||||||
|
|
||||||
for ebb in self.func.layout.ebbs() {
|
for ebb in self.func.layout.ebbs() {
|
||||||
|
|||||||
19
cranelift/filetests/filetests/verifier/jump_table.clif
Normal file
19
cranelift/filetests/filetests/verifier/jump_table.clif
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
test verifier
|
||||||
|
|
||||||
|
function %br_invalid_default(i64) {
|
||||||
|
jt0 = jump_table [ebb1, ebb1]
|
||||||
|
|
||||||
|
ebb0(v0: i64):
|
||||||
|
br_table.i64 v0, ebb2, jt0 ; error: invalid ebb reference ebb2
|
||||||
|
ebb1:
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
function %br(i64) {
|
||||||
|
jt0 = jump_table [ebb1, ebb2] ; error: invalid ebb reference ebb2
|
||||||
|
|
||||||
|
ebb0(v0: i64):
|
||||||
|
br_table.i64 v0, ebb1, jt0
|
||||||
|
ebb1:
|
||||||
|
return
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user