Skip to content

Commit

Permalink
abi.decode("", ()) has no returns
Browse files Browse the repository at this point in the history
This should be compiled as: function returning void

Fixes: #1727

Signed-off-by: Sean Young <sean@mess.org>
  • Loading branch information
seanyoung committed Feb 8, 2025
1 parent 07ad1a1 commit 6c1a844
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 14 deletions.
7 changes: 6 additions & 1 deletion src/codegen/expression.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3198,7 +3198,12 @@ pub fn emit_function_call(
args,
} => {
let data = expression(&args[0], cfg, caller_contract_no, func, ns, vartab, opt);
abi_decode(loc, &data, tys, ns, vartab, cfg, None)

if tys.len() == 1 && tys[0] == Type::Void {
vec![Expression::Poison]
} else {
abi_decode(loc, &data, tys, ns, vartab, cfg, None)
}
}
_ => unreachable!(),
}
Expand Down
32 changes: 19 additions & 13 deletions src/sema/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1135,24 +1135,30 @@ pub(super) fn resolve_namespace_call(
let mut tys = Vec::new();
let mut broken = false;

for arg in parameter_list_to_expr_list(&args[1], diagnostics)? {
let ty = ns.resolve_type(
context.file_no,
context.contract_no,
ResolveTypeContext::None,
arg.strip_parentheses(),
diagnostics,
)?;
let ty_exprs = parameter_list_to_expr_list(&args[1], diagnostics)?;

if ty.is_mapping() || ty.is_recursive(ns) {
diagnostics.push(Diagnostic::error(
if ty_exprs.is_empty() {
tys.push(Type::Void);
} else {
for arg in ty_exprs {
let ty = ns.resolve_type(
context.file_no,
context.contract_no,
ResolveTypeContext::None,
arg.strip_parentheses(),
diagnostics,
)?;

if ty.is_mapping() || ty.is_recursive(ns) {
diagnostics.push(Diagnostic::error(
*loc,
format!("Invalid type '{}': mappings and recursive types cannot be abi decoded or encoded", ty.to_string(ns))
));
broken = true;
}
broken = true;
}

tys.push(ty);
tys.push(ty);
}
}

return if broken {
Expand Down
7 changes: 7 additions & 0 deletions tests/contract_testcases/evm/builtins/abi_decode_unit_1.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
contract C {
function g() public pure {
abi.decode("abc", ());
}
}

// ---- Expect: diagnostics ----
8 changes: 8 additions & 0 deletions tests/contract_testcases/evm/builtins/abi_decode_unit_2.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
contract C {
function f() public pure {
int a =abi.decode("abc", ());
}
}

// ---- Expect: diagnostics ----
// error: 3:16-37: function or method does not return a value

1 comment on commit 6c1a844

@Eloutmanixx
Copy link

Choose a reason for hiding this comment

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

👍👋

Please sign in to comment.