소스 검색

abi.decode("", ()) has no returns (#1732)

This should be compiled as: function returning void

Fixes: https://github.com/hyperledger-solang/solang/issues/1727

Signed-off-by: Sean Young <sean@mess.org>
Sean Young 9 달 전
부모
커밋
fa338eba3b

+ 6 - 1
src/codegen/expression.rs

@@ -3198,7 +3198,12 @@ pub fn emit_function_call(
             args,
             args,
         } => {
         } => {
             let data = expression(&args[0], cfg, caller_contract_no, func, ns, vartab, opt);
             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!(),
         _ => unreachable!(),
     }
     }

+ 19 - 13
src/sema/builtin.rs

@@ -1135,24 +1135,30 @@ pub(super) fn resolve_namespace_call(
         let mut tys = Vec::new();
         let mut tys = Vec::new();
         let mut broken = false;
         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,
                     *loc,
                     format!("Invalid type '{}': mappings and recursive types cannot be abi decoded or encoded", ty.to_string(ns))
                     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 {
         return if broken {

+ 7 - 0
tests/contract_testcases/evm/builtins/abi_decode_unit_1.sol

@@ -0,0 +1,7 @@
+contract C {
+    function g() public pure {
+        abi.decode("abc", ());
+    }
+}
+
+// ---- Expect: diagnostics ----

+ 8 - 0
tests/contract_testcases/evm/builtins/abi_decode_unit_2.sol

@@ -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