Skip to content

Commit

Permalink
rune: Fix freed address with diverging conditions
Browse files Browse the repository at this point in the history
  • Loading branch information
udoprog committed Oct 8, 2024
1 parent 1f0e860 commit 9c525d7
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 9 deletions.
16 changes: 7 additions & 9 deletions crates/rune/src/compile/v1/assemble.rs
Original file line number Diff line number Diff line change
Expand Up @@ -640,17 +640,18 @@ fn condition<'a, 'hir>(
match *hir {
hir::Condition::Expr(hir) => {
let scope = cx.scopes.child(hir)?;
let mut addr = cx.scopes.alloc(hir)?;
let mut addr = cx.scopes.alloc(hir)?.with_name("expression condition");

let asm = if expr(cx, hir, &mut addr)?.converging() {
cx.asm.jump_if(addr.addr(), then_label, hir)?;
addr.free()?;
Asm::new(hir, (scope, Pattern::Irrefutable))
} else {
addr.free()?;
cx.scopes.pop(hir, scope)?;
Asm::diverge(hir)
};

addr.free()?;
Ok(asm)
}
hir::Condition::ExprLet(hir) => {
Expand Down Expand Up @@ -2412,15 +2413,12 @@ fn expr_match<'a, 'hir>(
let mut converges = true;

if let Some(condition) = branch.condition {
let span = condition;
let mut cond = cx.scopes.defer(condition);

let scope = cx.scopes.child(span)?;
let scope = cx.scopes.child(condition)?;
let mut cond = cx.scopes.alloc(condition)?.with_name("match condition");

if expr(cx, condition, &mut cond)?.converging() {
cx.asm
.jump_if_not(cond.addr()?.addr(), &match_false, span)?;
cx.asm.jump(&branch_label, span)?;
cx.asm.jump_if_not(cond.addr(), &match_false, condition)?;
cx.asm.jump(&branch_label, condition)?;
} else {
converges = false;
}
Expand Down
14 changes: 14 additions & 0 deletions crates/rune/tests/bug_830.rn
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,17 @@ fn while_stmt() {

assert!(value);
}

#[test]
fn match_stmt() {
let value = true;

let value2 = match true {
false => false,
_ if value && false => panic!("should not be reached"),
true => true,
};

assert!(value);
assert!(value2);
}
36 changes: 36 additions & 0 deletions crates/rune/tests/diverging.rn
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#[test]
fn diverging_if() {
fn inner() {
if return true {
}

false
}

assert!(inner());
}

#[test]
fn diverging_condition_while() {
fn inner() {
while return true {
}

false
}

assert!(inner());
}

#[test]
fn diverging_condition_match() {
fn inner() {
match true {
false => false,
_ if return true => false,
true => false,
}
}

assert!(inner());
}

0 comments on commit 9c525d7

Please sign in to comment.