Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ Compiler Features:
* Yul Optimizer: Remove redundant prerequisite steps from the default optimizer sequence.

Bugfixes:
* Yul IR Code Generation: Encode custom error named parameters in declaration order instead of call-site order.


### 0.8.33 (2025-12-18)
Expand Down
2 changes: 1 addition & 1 deletion libsolidity/codegen/ir/IRGeneratorForStatements.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1167,7 +1167,7 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall)
{
auto const& errorConstructorCall = dynamic_cast<FunctionCall const&>(*arguments[1]);
appendCode() << m_utils.requireWithErrorFunction(errorConstructorCall) << "(" <<IRVariable(*arguments[0]).name();
for (auto argument: errorConstructorCall.arguments())
for (auto argument: errorConstructorCall.sortedArguments())
Copy link
Collaborator

@cameel cameel Feb 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dealing with named arguments is actually quite error prone. This is not the first time we have a bug of this kind (#9766). While the change here may be enough for the fix, I think we should also take some steps to prevent this happening yet again (could be a separate PR on top of the fix).

We have this FuncCallArguments struct. I think we should get rid of the arguments()/sortedArguments() pair and instead always pass around arguments in this container. Then make it iterable and only in the right, sorted order. We can keep a special method for accessing them in the call order for corner cases in which you actually do want that.

if (argument->annotation().type->sizeOnStack() > 0)
appendCode() << ", " << IRVariable(*argument).commaSeparatedList();
appendCode() << ")\n";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
error NamedArgsError2(uint256 a, uint256 b);
error NamedArgsError3(uint256 a, uint256 b, uint256 c);
error NamedArgsError4(uint256 a, string b, uint256 c, bool d);

contract C {
function trigger2() external pure {
require(false, NamedArgsError2({b: 7, a: 2}));
}
function trigger3() external pure {
require(false, NamedArgsError3({c: 9, a: 2, b: 7}));
}
function trigger4() external pure {
require(false, NamedArgsError4({b: "error", a: 2, c: 9, d: true}));
}
}

// ----
// trigger2() -> FAILURE, hex"59f176a3", hex"0000000000000000000000000000000000000000000000000000000000000002", hex"0000000000000000000000000000000000000000000000000000000000000007"
// trigger3() -> FAILURE, hex"b912b8d4", hex"0000000000000000000000000000000000000000000000000000000000000002", hex"0000000000000000000000000000000000000000000000000000000000000007", hex"0000000000000000000000000000000000000000000000000000000000000009"
// trigger4() -> FAILURE, hex"8ae9981b", hex"0000000000000000000000000000000000000000000000000000000000000002", hex"0000000000000000000000000000000000000000000000000000000000000080", hex"0000000000000000000000000000000000000000000000000000000000000009", hex"0000000000000000000000000000000000000000000000000000000000000001", hex"0000000000000000000000000000000000000000000000000000000000000005", hex"6572726f72000000000000000000000000000000000000000000000000000000"