Browse Source

Optimize modifier CFGs (#1391)

Cyrill Leutwiler 2 years ago
parent
commit
d0d65283ba
2 changed files with 45 additions and 11 deletions
  1. 5 11
      src/codegen/cfg.rs
  2. 40 0
      tests/codegen_testcases/solidity/modifier_opt.sol

+ 5 - 11
src/codegen/cfg.rs

@@ -1463,6 +1463,10 @@ pub fn generate_cfg(
     }
 
     let mut cfg = function_cfg(contract_no, function_no, ns, opt);
+    let ast_fn = function_no
+        .map(ASTFunction::SolidityFunction)
+        .unwrap_or(ASTFunction::None);
+    optimize_and_check_cfg(&mut cfg, ns, ast_fn, opt);
 
     if let Some(func_no) = function_no {
         let func = &ns.functions[func_no];
@@ -1488,6 +1492,7 @@ pub fn generate_cfg(
                     ns,
                     opt,
                 );
+                optimize_and_check_cfg(&mut cfg, ns, ast_fn, opt);
             }
 
             cfg.public = public;
@@ -1496,17 +1501,6 @@ pub fn generate_cfg(
         }
     }
 
-    optimize_and_check_cfg(
-        &mut cfg,
-        ns,
-        if let Some(func_no) = function_no {
-            ASTFunction::SolidityFunction(func_no)
-        } else {
-            ASTFunction::None
-        },
-        opt,
-    );
-
     all_cfgs[cfg_no] = cfg;
 }
 

+ 40 - 0
tests/codegen_testcases/solidity/modifier_opt.sol

@@ -0,0 +1,40 @@
+// RUN: --target substrate --emit cfg
+
+contract Test {
+    // BEGIN-CHECK: Test::testMethod::modifier0::m1
+    modifier m1() {
+        require(msg.value != 1 - 1);
+        _;
+        require(msg.value != 2 ** 128 - 1);
+
+        // CHECK: block0: # entry
+        // CHECK: branchcond (uint128((builtin Value ())) != uint128 0),
+        // NOT-CHECK: uint128 1 - uint128 1
+
+        // CHECK: branchcond (uint128((builtin Value ())) != uint128 -1),
+        // NOT-CHECK: uint128 2 ** uint128 127
+    }
+
+    // BEGIN-CHECK: Test::testMethod::modifier1::m2
+    modifier m2() {
+        require(msg.value != 2 ** 128 - 1);
+        _;
+        require(msg.value != 1 - 1);
+
+        // CHECK: block0: # entry
+        // CHECK: branchcond (uint128((builtin Value ())) != uint128 -1),
+        // NOT-CHECK: uint128 2 ** uint128 127,
+
+        // CHECK: branchcond (uint128((builtin Value ())) != uint128 0),
+        // NOT-CHECK: uint128 1 - uint128 1
+    }
+
+    // BEGIN-CHECK: Test::function::testMethod
+    function testMethod() public payable m1 m2 returns (uint256) {
+        return 2 ** 256 - 1;
+
+        // CHECK: block0: # entry
+        // CHECK: return uint256 -1
+        // NOT-CHECK: (uint256 2 ** uint256 256) - uint256 1
+    }
+}