diff --git a/src/parser/parsers.h b/src/parser/parsers.h index 48f65c497e0..c90e2c01d1f 100644 --- a/src/parser/parsers.h +++ b/src/parser/parsers.h @@ -1005,6 +1005,13 @@ template MaybeResult<> foldedinstr(Ctx& ctx) { auto inst = plaininstr(ctx, std::move(info.annotations)); assert(inst && "unexpectedly failed to parse instruction"); CHECK_ERR(inst); + // We have already parsed the instruction, so we generally know where it + // ends. But there may have been some invalid extra immediates (e.g. + // invalid memory indices) that we only realize are invalid now that we've + // parsed the instruction for real. + if (ctx.in.getPos() != *info.end) { + return ctx.in.err("expected end of instruction"); + } assert(ctx.in.getPos() == *info.end && "expected end of instruction"); continue; } diff --git a/test/lit/parse-bad-optional-memidx.wast b/test/lit/parse-bad-optional-memidx.wast new file mode 100644 index 00000000000..57438d6d2fd --- /dev/null +++ b/test/lit/parse-bad-optional-memidx.wast @@ -0,0 +1,17 @@ +;; Regression test for a parser bug where the invalid memory index followed by +;; another immediate caused an assertion failure. + +;; RUN: not wasm-opt -all %s 2>&1 | filecheck %s + +;; CHECK: Fatal: 12:22: error: expected end of instruction + +(module + (memory 1 1) + + (func $v128.load16_lane1 (param $0 i32) (param $1 v128) (result v128) + (v128.load16_lane 1 0 ;; invalid memory index + (local.get $0) + (local.get $1) + ) + ) +) \ No newline at end of file