Skip to content

Commit 46e1f81

Browse files
authored
Merge pull request #15542 from ipsilon/verbatim-side-effect-fix
Fix verbatim control flow side effects
2 parents 4231717 + 1b3d549 commit 46e1f81

File tree

4 files changed

+29
-2
lines changed

4 files changed

+29
-2
lines changed

docs/yul.rst

+2-1
Original file line numberDiff line numberDiff line change
@@ -1094,7 +1094,8 @@ the compiler. Violations of these restrictions can result in
10941094
undefined behavior.
10951095

10961096
- Control-flow should not jump into or out of verbatim blocks,
1097-
but it can jump within the same verbatim block.
1097+
but it can jump within the same verbatim block. In particular,
1098+
reverting or returning from the block is *not* allowed.
10981099
- Stack contents apart from the input and output parameters
10991100
should not be accessed.
11001101
- The stack height difference should be exactly ``m - n``

libyul/ControlFlowSideEffects.h

+6
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,12 @@ struct ControlFlowSideEffects
6868

6969
return controlFlowSideEffects;
7070
}
71+
72+
/// @returns the worst-case control flow side effects.
73+
static ControlFlowSideEffects worst()
74+
{
75+
return ControlFlowSideEffects{true, true, true};
76+
}
7177
};
7278

7379
}

libyul/backends/evm/EVMDialect.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -566,7 +566,7 @@ BuiltinFunctionForEVM EVMDialect::createVerbatimFunction(size_t _arguments, size
566566
1 + _arguments,
567567
_returnVariables,
568568
SideEffects::worst(),
569-
ControlFlowSideEffects{},
569+
ControlFlowSideEffects::worst(), // Worst control flow side effects because verbatim can do anything.
570570
std::vector<std::optional<LiteralKind>>{LiteralKind::String} + std::vector<std::optional<LiteralKind>>(_arguments),
571571
[=](
572572
FunctionCall const& _call,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
let x := 0
3+
let y := 1
4+
sstore(x, y)
5+
// opcodes: PUSH1 0x00 DUP1 RETURN
6+
// SSTORE is not redundant due to the RETURN hidden in the verbatim block. It must not be removed.
7+
verbatim_0i_0o(hex"600080F3")
8+
revert(0,0)
9+
}
10+
// ----
11+
// step: unusedStoreEliminator
12+
//
13+
// {
14+
// {
15+
// let x := 0
16+
// sstore(x, 1)
17+
// verbatim_0i_0o("`\x00\x80\xf3")
18+
// revert(0, 0)
19+
// }
20+
// }

0 commit comments

Comments
 (0)