mirror of
https://github.com/pezkuwichain/revive.git
synced 2026-10-20 18:56:17 +00:00
add integration test for i32 operand overflow in PVM linker const fold (#552)
Closes #551 --------- Signed-off-by: xermicus <cyrill@parity.io>
This commit is contained in:
1 parent
3d70def08c
commit
541955d31b
5 files changed
+94
-26
No files matched your search
Generated
+22
-22
@@ -8695,16 +8695,16 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "polkavm"
|
name = "polkavm"
|
||||||
version = "0.34.0"
|
version = "0.35.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "90d020e05b17d1d7612045ff1244efb33c37e54838be5c8a6af00e7e10adc019"
|
checksum = "1e169701bf52ffe9abafea76f0519d526c736a4deea7e2cd70fc51b3bbf1ba81"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"log",
|
"log",
|
||||||
"picosimd",
|
"picosimd",
|
||||||
"polkavm-assembler 0.34.0",
|
"polkavm-assembler 0.35.0",
|
||||||
"polkavm-common 0.34.0",
|
"polkavm-common 0.35.0",
|
||||||
"polkavm-linux-raw 0.34.0",
|
"polkavm-linux-raw 0.35.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -8718,9 +8718,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "polkavm-assembler"
|
name = "polkavm-assembler"
|
||||||
version = "0.34.0"
|
version = "0.35.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a3145b14db78aaa7c37bd401906f0ccf3af2dc7ff6bebb3d89a88967ae14a4dc"
|
checksum = "6dddb5cf523ca1c8de5a1a265438aa0e96fbf812e9f90a2f300a4c550bd8a9e9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"log",
|
"log",
|
||||||
]
|
]
|
||||||
@@ -8748,13 +8748,13 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "polkavm-common"
|
name = "polkavm-common"
|
||||||
version = "0.34.0"
|
version = "0.35.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "67b1bdbd3d706e8fe695403f501c218f20550e48181e2a56033665ecba3eb4c2"
|
checksum = "b20e5a47dd9ad7bb43013676a18074fca2573dd8270774a7d2ad286b57bc710f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"log",
|
"log",
|
||||||
"picosimd",
|
"picosimd",
|
||||||
"polkavm-assembler 0.34.0",
|
"polkavm-assembler 0.35.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -8821,15 +8821,15 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "polkavm-disassembler"
|
name = "polkavm-disassembler"
|
||||||
version = "0.34.0"
|
version = "0.35.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "803bd60570ae34a63fe97865d58d02db9bca5af6f4ef0059c6856edeb5ea5849"
|
checksum = "a5baf1b6eceba9f08810d9d17e54b82000e848f0877c3a339c75bb60b4db5dfc"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap",
|
"clap",
|
||||||
"iced-x86",
|
"iced-x86",
|
||||||
"polkavm 0.34.0",
|
"polkavm 0.35.0",
|
||||||
"polkavm-common 0.34.0",
|
"polkavm-common 0.35.0",
|
||||||
"polkavm-linker 0.34.0",
|
"polkavm-linker 0.35.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -8850,16 +8850,16 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "polkavm-linker"
|
name = "polkavm-linker"
|
||||||
version = "0.34.0"
|
version = "0.35.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1f49e142e81d23765cde731adf4263b4c3b77a06801ae603bbe5a71933de9ca0"
|
checksum = "96b5c8083bf6c33ff0d9254bbe500872c18a82f2801c5879693f10c16816275e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"dirs",
|
"dirs",
|
||||||
"gimli 0.31.1",
|
"gimli 0.31.1",
|
||||||
"hashbrown 0.14.5",
|
"hashbrown 0.14.5",
|
||||||
"log",
|
"log",
|
||||||
"object 0.36.7",
|
"object 0.36.7",
|
||||||
"polkavm-common 0.34.0",
|
"polkavm-common 0.35.0",
|
||||||
"regalloc2 0.9.3",
|
"regalloc2 0.9.3",
|
||||||
"rustc-demangle",
|
"rustc-demangle",
|
||||||
]
|
]
|
||||||
@@ -8872,9 +8872,9 @@ checksum = "42063d4a1c52e569f7794df27dab3e19c9fa8946184023257bdbb43eb4a94be5"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "polkavm-linux-raw"
|
name = "polkavm-linux-raw"
|
||||||
version = "0.34.0"
|
version = "0.35.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ff4d1210eddaae35bb36479f99569fe6677ea47daefbeab1705ccc80ad246fc3"
|
checksum = "7689d791c6ab52782217ae904d0f5eb7b7cc125a90eb085069d38c15f5d5a53c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "poly1305"
|
name = "poly1305"
|
||||||
@@ -9527,7 +9527,7 @@ dependencies = [
|
|||||||
"anyhow",
|
"anyhow",
|
||||||
"libc",
|
"libc",
|
||||||
"lld-sys",
|
"lld-sys",
|
||||||
"polkavm-linker 0.34.0",
|
"polkavm-linker 0.35.0",
|
||||||
"revive-builtins",
|
"revive-builtins",
|
||||||
"tempfile",
|
"tempfile",
|
||||||
]
|
]
|
||||||
@@ -9562,7 +9562,7 @@ dependencies = [
|
|||||||
"itertools 0.14.0",
|
"itertools 0.14.0",
|
||||||
"libc",
|
"libc",
|
||||||
"num",
|
"num",
|
||||||
"polkavm-common 0.34.0",
|
"polkavm-common 0.35.0",
|
||||||
"polkavm-disassembler",
|
"polkavm-disassembler",
|
||||||
"revive-common",
|
"revive-common",
|
||||||
"revive-linker",
|
"revive-linker",
|
||||||
|
|||||||
+4
-4
@@ -49,10 +49,10 @@ which = "8.0"
|
|||||||
path-slash = "0.2"
|
path-slash = "0.2"
|
||||||
rayon = "1.11"
|
rayon = "1.11"
|
||||||
clap = { version = "4", default-features = false, features = ["derive"] }
|
clap = { version = "4", default-features = false, features = ["derive"] }
|
||||||
polkavm-common = "0.34.0"
|
polkavm-common = "0.35.0"
|
||||||
polkavm-linker = "0.34.0"
|
polkavm-linker = "0.35.0"
|
||||||
polkavm-disassembler = "0.34.0"
|
polkavm-disassembler = "0.35.0"
|
||||||
polkavm = "0.34.0"
|
polkavm = "0.35.0"
|
||||||
alloy-primitives = { version = "1.4", features = ["serde"] }
|
alloy-primitives = { version = "1.4", features = ["serde"] }
|
||||||
alloy-sol-types = "1.4"
|
alloy-sol-types = "1.4"
|
||||||
alloy-genesis = "1.1.2"
|
alloy-genesis = "1.1.2"
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
pragma solidity ^0.8.20;
|
||||||
|
|
||||||
|
/// Regression: at `-O3` (the `OptimizerSettings::cycles()` middle/back-end
|
||||||
|
/// level used by the differential harness) LLVM proves the low 64 bits of
|
||||||
|
/// `(a2 + (a0 << 64)) ^ a2` cancel to zero and narrows the surviving
|
||||||
|
/// `| 0x80000000 | 0x80000001` work down to native i32 lane operations.
|
||||||
|
/// The constant `0x80000000` (`2^31`) is materialized with `lui x, 0x80000`.
|
||||||
|
/// During link time the polkavm-linker (`program_from_elf.rs`) constant-folds
|
||||||
|
/// the narrowed 32-bit op through `OperationKind::apply_const`, whose `op32!`
|
||||||
|
/// macro does `i64 -> i32` via `try_into().expect("operand overflow")`. The
|
||||||
|
/// tracked constant for `0x80000000` does not fit the signed i32 range, so the
|
||||||
|
/// fold panics with `operand overflow: TryFromIntError` — an ICE instead of a
|
||||||
|
/// clean compile. solc's EVM backend has no such narrowing (everything is
|
||||||
|
/// 256-bit), so the same source compiles cleanly there.
|
||||||
|
contract LinkerI32BoundaryFoldBug {
|
||||||
|
function test(int256 a0, int256 a2) external pure returns (int256) {
|
||||||
|
int256 t1 = (a2 + (a0 * int256(18446744073709551616))) ^ a2; // low-64 cancel
|
||||||
|
t1 = t1 | int256(2147483648); // 0x80000000 (i32 sign boundary)
|
||||||
|
t1 = t1 | int256(2147483649); // 0x80000001
|
||||||
|
return t1;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -329,6 +329,20 @@ case!(
|
|||||||
const_return_overflow_bug,
|
const_return_overflow_bug,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
sol!(
|
||||||
|
contract LinkerI32BoundaryFoldBug {
|
||||||
|
function test(int256 a0, int256 a2) external pure returns (int256);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
case!(
|
||||||
|
"LinkerI32BoundaryFoldBug.sol",
|
||||||
|
LinkerI32BoundaryFoldBug,
|
||||||
|
testCall,
|
||||||
|
linker_i32_boundary_fold_bug,
|
||||||
|
a0: I256,
|
||||||
|
a2: I256
|
||||||
|
);
|
||||||
|
|
||||||
// `PanicInterveneBug` has only a `fallback()` — invoked by sending
|
// `PanicInterveneBug` has only a `fallback()` — invoked by sending
|
||||||
// raw calldata that doesn't match any selector. Empty calldata works.
|
// raw calldata that doesn't match any selector. Empty calldata works.
|
||||||
case!(
|
case!(
|
||||||
|
|||||||
@@ -494,6 +494,36 @@ fn const_return_offset_overflow_traps() {
|
|||||||
run_differential(actions);
|
run_differential(actions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Regression: at `-O3` LLVM proves the low 64 bits of
|
||||||
|
/// `(a2 + (a0 << 64)) ^ a2` cancel and narrows the trailing
|
||||||
|
/// `| 0x80000000 | 0x80000001` down to native i32 lane operations,
|
||||||
|
/// materializing `0x80000000` (`2^31`) via `lui x, 0x80000`. The
|
||||||
|
/// polkavm-linker's constant propagation then folds the narrowed 32-bit
|
||||||
|
/// op through `OperationKind::apply_const`, whose `op32!` macro converts
|
||||||
|
/// `i64 -> i32` with `try_into().expect("operand overflow")`. The tracked
|
||||||
|
/// constant `0x80000000` does not fit the signed i32 range, so the fold
|
||||||
|
/// panics (`operand overflow: TryFromIntError`) — an ICE instead of a
|
||||||
|
/// clean compile. solc's EVM backend has no such narrowing (all ops are
|
||||||
|
/// 256-bit) so the same source compiles cleanly there.
|
||||||
|
#[test]
|
||||||
|
fn linker_i32_boundary_constant_fold() {
|
||||||
|
let mut actions = instantiate(
|
||||||
|
"contracts/LinkerI32BoundaryFoldBug.sol",
|
||||||
|
"LinkerI32BoundaryFoldBug",
|
||||||
|
);
|
||||||
|
let a0 = I256::try_from(0x0123456789abcdef_i64).unwrap();
|
||||||
|
let a2 = I256::try_from(-0x7654321076543210_i64).unwrap();
|
||||||
|
actions.push(Call {
|
||||||
|
origin: TestAddress::Alice,
|
||||||
|
dest: TestAddress::Instantiated(0),
|
||||||
|
value: 0,
|
||||||
|
gas_limit: None,
|
||||||
|
storage_deposit_limit: None,
|
||||||
|
data: Contract::linker_i32_boundary_fold_bug(a0, a2).calldata,
|
||||||
|
});
|
||||||
|
run_differential(actions);
|
||||||
|
}
|
||||||
|
|
||||||
/// Regression: `simplify.rs::find_panic_pattern_backwards` walks the
|
/// Regression: `simplify.rs::find_panic_pattern_backwards` walks the
|
||||||
/// statement list backwards from `revert(0, 0x24)` and accepts an
|
/// statement list backwards from `revert(0, 0x24)` and accepts an
|
||||||
/// `mstore` at offsets ≠ 0 / 4 as "safe filler" — it skips it in the
|
/// `mstore` at offsets ≠ 0 / 4 as "safe filler" — it skips it in the
|
||||||
|
|||||||
Reference in new issue
Block a user