Skip to content

Commit

Permalink
Error when ethdebug is used with optimization.
Browse files Browse the repository at this point in the history
  • Loading branch information
aarlt committed Jan 27, 2025
1 parent d3cccb9 commit 23d9607
Show file tree
Hide file tree
Showing 37 changed files with 2,362 additions and 373 deletions.
3 changes: 3 additions & 0 deletions libsolidity/interface/StandardCompiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1204,6 +1204,9 @@ std::variant<StandardCompiler::InputsAndSettings, Json> StandardCompiler::parseI
)
return formatFatalError(Error::Type::FatalError, "'settings.debug.debugInfo' can only include 'ethdebug', if output 'ir', 'irOptimized', 'evm.bytecode.ethdebug', or 'evm.deployedBytecode.ethdebug' was selected.");

if (isEthdebugRequested(ret.outputSelection) && (ret.optimiserSettings.runYulOptimiser || isArtifactRequested(ret.outputSelection, "*", "*", "irOptimized", false)))
return formatFatalError(Error::Type::FatalError, "Optimization is not yet supported with ethdebug.");

return {std::move(ret)};
}

Expand Down
15 changes: 9 additions & 6 deletions solc/CommandLineParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1485,15 +1485,18 @@ void CommandLineParser::processArgs()
);

bool incompatibleEthdebugOutputs =
m_options.compiler.outputs.asmJson || m_options.compiler.outputs.irAstJson || m_options.compiler.outputs.irOptimizedAstJson;
m_options.compiler.outputs.asmJson || m_options.compiler.outputs.irAstJson || m_options.compiler.outputs.irOptimizedAstJson ||
m_options.compiler.outputs.irOptimized || m_options.optimizer.optimizeYul || m_options.optimizer.optimizeEvmasm;

bool incompatibleEthdebugInputs = m_options.input.mode != InputMode::Compiler;

static std::string enableEthdebugMessage =
"--" + CompilerOutputs::componentName(&CompilerOutputs::ethdebug) + " / --" + CompilerOutputs::componentName(&CompilerOutputs::ethdebugRuntime);

static std::string enableIrMessage =
"--" + CompilerOutputs::componentName(&CompilerOutputs::ir) + " / --" + CompilerOutputs::componentName(&CompilerOutputs::irOptimized);
static std::string incompatibleEthdebugOptimizerMessage =
"--" + g_strOptimize + " / --" + CompilerOutputs::componentName(&CompilerOutputs::irOptimized);

static std::string enableIrMessage = "--" + CompilerOutputs::componentName(&CompilerOutputs::ir);

if (m_options.compiler.outputs.ethdebug || m_options.compiler.outputs.ethdebugRuntime)
{
Expand All @@ -1506,7 +1509,7 @@ void CommandLineParser::processArgs()
if (incompatibleEthdebugOutputs)
solThrow(
CommandLineValidationError,
enableEthdebugMessage + " output can only be used with " + enableIrMessage + "."
enableEthdebugMessage + " output can only be used with " + enableIrMessage + ". Optimization is not yet supported with ethdebug, e.g. no support for " + incompatibleEthdebugOptimizerMessage + " yet."
);

if (!m_options.output.debugInfoSelection.has_value())
Expand All @@ -1526,11 +1529,11 @@ void CommandLineParser::processArgs()

if (
m_options.output.debugInfoSelection.has_value() && m_options.output.debugInfoSelection->ethdebug &&
(!(m_options.compiler.outputs.ir || m_options.compiler.outputs.irOptimized || m_options.compiler.outputs.ethdebug || m_options.compiler.outputs.ethdebugRuntime) || incompatibleEthdebugOutputs)
(!(m_options.compiler.outputs.ir || m_options.compiler.outputs.ethdebug || m_options.compiler.outputs.ethdebugRuntime) || incompatibleEthdebugOutputs)
)
solThrow(
CommandLineValidationError,
"--debug-info ethdebug can only be used with " + enableIrMessage + " and/or " + enableEthdebugMessage + "."
"--debug-info ethdebug can only be used with " + enableIrMessage + " and/or " + enableEthdebugMessage + ". Optimization is not yet supported with ethdebug, e.g. no support for " + incompatibleEthdebugOptimizerMessage + " yet."
);

if (m_options.output.debugInfoSelection.has_value() && m_options.output.debugInfoSelection->ethdebug && incompatibleEthdebugInputs)
Expand Down
2 changes: 1 addition & 1 deletion test/cmdlineTests/ethdebug/args
Original file line number Diff line number Diff line change
@@ -1 +1 @@
--ethdebug --via-ir --optimize --ir-optimized
--ethdebug --via-ir --ir
111 changes: 95 additions & 16 deletions test/cmdlineTests/ethdebug/output
Original file line number Diff line number Diff line change
Expand Up @@ -2,41 +2,120 @@
{"sources":["ethdebug/input.sol"]}

======= ethdebug/input.sol:C =======
Optimized IR:
IR:
/// ethdebug: enabled
/// @use-src 0:"ethdebug/input.sol"
object "C_6" {
code {
{
/// @src 0:60:101 "contract C {..."
mstore(64, memoryguard(128))
if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }

constructor_C_6()

let _1 := allocate_unbounded()
codecopy(_1, dataoffset("C_6_deployed"), datasize("C_6_deployed"))

return(_1, datasize("C_6_deployed"))

function allocate_unbounded() -> memPtr {
memPtr := mload(64)
}

function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {
revert(0, 0)
}

/// @src 0:60:101 "contract C {..."
function constructor_C_6() {

/// @src 0:60:101 "contract C {..."
let _1 := memoryguard(0x80)
mstore(64, _1)
if callvalue() { revert(0, 0) }
let _2 := datasize("C_6_deployed")
codecopy(_1, dataoffset("C_6_deployed"), _2)
return(_1, _2)

}
/// @src 0:60:101 "contract C {..."

}
/// @use-src 0:"ethdebug/input.sol"
object "C_6_deployed" {
code {
/// @src 0:60:101 "contract C {..."
mstore(64, memoryguard(128))

if iszero(lt(calldatasize(), 4))
{
/// @src 0:60:101 "contract C {..."
if iszero(lt(calldatasize(), 4))
let selector := shift_right_224_unsigned(calldataload(0))
switch selector

case 0x26121ff0
{
if eq(0x26121ff0, shr(224, calldataload(0)))
{
if callvalue() { revert(0, 0) }
if slt(add(calldatasize(), not(3)), 0) { revert(0, 0) }
return(0, 0)
}
// f()

external_fun_f_5()
}

default {}
}

revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()

function shift_right_224_unsigned(value) -> newValue {
newValue :=

shr(224, value)

}

function allocate_unbounded() -> memPtr {
memPtr := mload(64)
}

function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {
revert(0, 0)
}

function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() {
revert(0, 0)
}

function abi_decode_tuple_(headStart, dataEnd) {
if slt(sub(dataEnd, headStart), 0) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() }

}

function abi_encode_tuple__to__fromStack(headStart ) -> tail {
tail := add(headStart, 0)

}

function external_fun_f_5() {

if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }
abi_decode_tuple_(4, calldatasize())
fun_f_5()
let memPos := allocate_unbounded()
let memEnd := abi_encode_tuple__to__fromStack(memPos )
return(memPos, sub(memEnd, memPos))

}

function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() {
revert(0, 0)
}

/// @ast-id 5
/// @src 0:77:99 "function f() public {}"
function fun_f_5() {

}
/// @src 0:60:101 "contract C {..."

}

data ".metadata" hex"<BYTECODE REMOVED>"
}

}


Debug Data (ethdebug/format/program):
{}
2 changes: 1 addition & 1 deletion test/cmdlineTests/ethdebug_and_ethdebug_runtime/args
Original file line number Diff line number Diff line change
@@ -1 +1 @@
--ethdebug-runtime --ethdebug --via-ir --optimize --ir-optimized
--ethdebug-runtime --ethdebug --via-ir --ir
111 changes: 95 additions & 16 deletions test/cmdlineTests/ethdebug_and_ethdebug_runtime/output
Original file line number Diff line number Diff line change
Expand Up @@ -2,42 +2,121 @@
{"sources":["ethdebug_and_ethdebug_runtime/input.sol"]}

======= ethdebug_and_ethdebug_runtime/input.sol:C =======
Optimized IR:
IR:
/// ethdebug: enabled
/// @use-src 0:"ethdebug_and_ethdebug_runtime/input.sol"
object "C_6" {
code {
{
/// @src 0:60:101 "contract C {..."
mstore(64, memoryguard(128))
if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }

constructor_C_6()

let _1 := allocate_unbounded()
codecopy(_1, dataoffset("C_6_deployed"), datasize("C_6_deployed"))

return(_1, datasize("C_6_deployed"))

function allocate_unbounded() -> memPtr {
memPtr := mload(64)
}

function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {
revert(0, 0)
}

/// @src 0:60:101 "contract C {..."
function constructor_C_6() {

/// @src 0:60:101 "contract C {..."
let _1 := memoryguard(0x80)
mstore(64, _1)
if callvalue() { revert(0, 0) }
let _2 := datasize("C_6_deployed")
codecopy(_1, dataoffset("C_6_deployed"), _2)
return(_1, _2)

}
/// @src 0:60:101 "contract C {..."

}
/// @use-src 0:"ethdebug_and_ethdebug_runtime/input.sol"
object "C_6_deployed" {
code {
/// @src 0:60:101 "contract C {..."
mstore(64, memoryguard(128))

if iszero(lt(calldatasize(), 4))
{
/// @src 0:60:101 "contract C {..."
if iszero(lt(calldatasize(), 4))
let selector := shift_right_224_unsigned(calldataload(0))
switch selector

case 0x26121ff0
{
if eq(0x26121ff0, shr(224, calldataload(0)))
{
if callvalue() { revert(0, 0) }
if slt(add(calldatasize(), not(3)), 0) { revert(0, 0) }
return(0, 0)
}
// f()

external_fun_f_5()
}

default {}
}

revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()

function shift_right_224_unsigned(value) -> newValue {
newValue :=

shr(224, value)

}

function allocate_unbounded() -> memPtr {
memPtr := mload(64)
}

function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {
revert(0, 0)
}

function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() {
revert(0, 0)
}

function abi_decode_tuple_(headStart, dataEnd) {
if slt(sub(dataEnd, headStart), 0) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() }

}

function abi_encode_tuple__to__fromStack(headStart ) -> tail {
tail := add(headStart, 0)

}

function external_fun_f_5() {

if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }
abi_decode_tuple_(4, calldatasize())
fun_f_5()
let memPos := allocate_unbounded()
let memEnd := abi_encode_tuple__to__fromStack(memPos )
return(memPos, sub(memEnd, memPos))

}

function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() {
revert(0, 0)
}

/// @ast-id 5
/// @src 0:77:99 "function f() public {}"
function fun_f_5() {

}
/// @src 0:60:101 "contract C {..."

}

data ".metadata" hex"<BYTECODE REMOVED>"
}

}


Debug Data (ethdebug/format/program):
{}
Debug Data of the runtime part (ethdebug/format/program):
Expand Down
1 change: 1 addition & 0 deletions test/cmdlineTests/ethdebug_enabled_optimization/args
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
--ethdebug --via-ir --optimize --ir-optimized
1 change: 1 addition & 0 deletions test/cmdlineTests/ethdebug_enabled_optimization/err
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Error: --ethdebug / --ethdebug-runtime output can only be used with --ir. Optimization is not yet supported with ethdebug, e.g. no support for --optimize / --ir-optimized yet.
1 change: 1 addition & 0 deletions test/cmdlineTests/ethdebug_enabled_optimization/exit
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1
7 changes: 7 additions & 0 deletions test/cmdlineTests/ethdebug_enabled_optimization/input.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// SPDX-License-Identifier: GPL-2.0
pragma solidity >=0.0;

contract C {
function f() public {}
}

2 changes: 1 addition & 1 deletion test/cmdlineTests/ethdebug_runtime/args
Original file line number Diff line number Diff line change
@@ -1 +1 @@
--ethdebug-runtime --via-ir --optimize --ir-optimized
--ethdebug-runtime --via-ir --ir
Loading

0 comments on commit 23d9607

Please sign in to comment.