aptos-core
aptos-core copied to clipboard
[Bug][compiler-v2] Bytecode verification error when multiple mutable references are used in a particular order
🐛 Bug
Consider the following program:
public fun test1(): u64 {
let x = 0;
let r1 = &mut x;
let r2 = &mut x;
*r1 + *r2
}
public fun test2(): u64 {
let x = 0;
let r1 = &mut x;
let r2 = &mut x;
*r2 + *r1 // <- changed order here
}
v1 and v2 compiler and run test1 without any issues, but on test2:
- v1 gives a compiler error
- v2 does not give a normal compiler error but gives a "bytecode verification failure bug" error due to
READREF_EXISTS_MUTABLE_BORROW_ERROR. We should instead provide a proper compiler error.
There are similar variations of the same problem:
public fun test3() {
let x = 0;
let r1 = &mut x;
let r2 = &mut x;
let _ = *r1;
let _ = *r2;
}
public fun test4() {
let x = 0;
let r1 = &mut x;
let r2 = &mut x;
let _ = *r2; // <- order changed
let _ = *r1; // <-
}
v1 and v2 compiler and run test3 without any issues, but on test4:
- v1 gives a compiler error
- v2 does not give a normal compiler error but gives a "bytecode verification failure bug" error due to
READREF_EXISTS_MUTABLE_BORROW_ERROR.
@brmataptos asked for the generated bytecode, so here it is for the first pair:
public test1(): u64 /* def_idx: 0 */ {
L0: loc0: u64
L1: loc1: &mut u64
L2: loc2: &mut u64
B0:
0: LdU64(0)
1: StLoc[0](loc0: u64)
2: MutBorrowLoc[0](loc0: u64)
3: MutBorrowLoc[0](loc0: u64)
4: StLoc[1](loc1: &mut u64)
5: StLoc[2](loc2: &mut u64)
6: MoveLoc[2](loc2: &mut u64)
7: ReadRef
8: MoveLoc[1](loc1: &mut u64)
9: ReadRef
10: Add
11: Ret
}
public test2(): u64 /* def_idx: 0 */ {
L0: loc0: u64
L1: loc1: u64
L2: loc2: &mut u64
L3: loc3: u64
B0:
0: LdU64(0)
1: StLoc[0](loc0: u64)
2: MutBorrowLoc[0](loc0: u64)
3: MutBorrowLoc[0](loc0: u64)
4: ReadRef
5: StLoc[1](loc1: u64)
6: StLoc[2](loc2: &mut u64)
7: MoveLoc[2](loc2: &mut u64)
8: ReadRef
9: StLoc[3](loc3: u64)
10: MoveLoc[1](loc1: u64)
11: MoveLoc[3](loc3: u64)
12: Add
13: Ret
}
Mitigated by #13469 so downgrading priority to medium