Пример #1
0
    def visitAssignmentStatement(self, ast: AssignmentStatement):
        lhs = ast.lhs
        rhs = ast.rhs
        if has_side_effects(lhs) or has_side_effects(rhs):
            ast.before_analysis = ast.before_analysis.separate_all()

        # visit expression
        self.visit(ast.lhs)
        self.visit(ast.rhs)

        # state after assignment
        after = ast.before_analysis.copy()
        recursive_assign(lhs, rhs, after)

        # save state
        ast.after_analysis = after
Пример #2
0
 def test_side_effects(self):
     ast = get_processed_ast(self.example.code(),
                             type_check=False,
                             solc_check=False)
     e = has_side_effects(ast)
     if self.has_side_effects() is not None:
         self.assertEqual(e, self.has_side_effects())
Пример #3
0
 def analyze(self, cond, before_analysis: PartitionState) -> PartitionState:
     if has_side_effects(cond):
         return before_analysis.copy().separate_all()
     else:
         self._neg = False
         self._analysis = before_analysis.copy()
         self.visit(cond)
         return self._analysis
Пример #4
0
    def visitDoWhileStatement(self, ast: DoWhileStatement):
        # Body either executes with or without condition, but it is also possible that it is not executed at all
        # No information about condition before the body
        # After the loop, the condition is false

        # Could be subsequent loop iteration after condition with side effect
        cond_se = has_side_effects(ast.condition)
        if cond_se or has_side_effects(ast.body):
            ast.before_analysis = ast.before_analysis.separate_all()

        ast.body.before_analysis = ast.before_analysis.copy()
        self.visit(ast.body)

        # ast.before_analysis is only used by expressions inside condition -> body has already happened at that point
        ast.before_analysis = ast.body.after_analysis.copy()
        ast.after_analysis = self.cond_analyzer.analyze(
            ast.condition.unop('!'), ast.before_analysis)
Пример #5
0
    def visitExpressionStatement(self, ast: ExpressionStatement):
        if has_side_effects(ast.expr):
            ast.before_analysis = ast.before_analysis.separate_all()

        # visit expression
        self.visit(ast.expr)

        # if expression has effect, we are already at TOP
        ast.after_analysis = ast.before_analysis.copy()
Пример #6
0
    def visitWhileStatement(self, ast: WhileStatement):
        # Body always executes after the condition, but it is also possible that it is not executed at all
        # Condition is true before the body
        # After the loop, the condition is false

        if has_side_effects(ast.condition) or has_side_effects(ast.body):
            ast.before_analysis = ast.before_analysis.separate_all()

        before_body = self.cond_analyzer.analyze(ast.condition,
                                                 ast.before_analysis)
        ast.body.before_analysis = before_body
        self.visit(ast.body)

        # Either no loop iteration or at least one loop iteration
        skip_loop = self.cond_analyzer.analyze(ast.condition.unop('!'),
                                               ast.before_analysis)
        did_loop = self.cond_analyzer.analyze(ast.condition.unop('!'),
                                              ast.body.after_analysis)

        # join
        ast.after_analysis = skip_loop.join(did_loop)
Пример #7
0
    def visitForStatement(self, ast: ForStatement):
        last = ast.before_analysis.copy()

        # add names introduced in init
        for name in ast.names.values():
            last.insert(name)

        if ast.init is not None:
            ast.init.before_analysis = last.copy()
            self.visit(ast.init)
            ast.before_analysis = ast.init.after_analysis.copy(
            )  # init should be taken into account when looking up things in the condition

        if has_side_effects(ast.condition) or has_side_effects(
                ast.body) or (ast.update is not None
                              and has_side_effects(ast.update)):
            ast.before_analysis = last.separate_all()

        ast.body.before_analysis = self.cond_analyzer.analyze(
            ast.condition, ast.before_analysis)
        self.visit(ast.body)
        if ast.update is not None:
            # Update is always executed after the body (if it is executed)
            ast.update.before_analysis = ast.body.after_analysis.copy()
            self.visit(ast.update)

        skip_loop = self.cond_analyzer.analyze(ast.condition.unop('!'),
                                               ast.init.after_analysis)
        did_loop = self.cond_analyzer.analyze(
            ast.condition.unop('!'), ast.update.after_analysis
            if ast.update else ast.body.after_analysis)

        # join
        ast.after_analysis = skip_loop.join(did_loop)

        # drop names introduced in init
        for name in ast.names.values():
            ast.after_analysis.remove(name)
Пример #8
0
    def visitRequireStatement(self, ast: RequireStatement):
        if has_side_effects(ast.condition):
            ast.before_analysis = ast.before_analysis.separate_all()

        self.visit(ast.condition)

        # state after require
        after = ast.before_analysis.copy()

        # make state more precise
        c = ast.condition
        if isinstance(c, FunctionCallExpr) and isinstance(
                c.func, BuiltinFunction) and c.func.op == '==':
            lhs = c.args[0].privacy_annotation_label()
            rhs = c.args[1].privacy_annotation_label()
            if lhs and rhs:
                after.merge(lhs, rhs)

        ast.after_analysis = after
Пример #9
0
    def visitVariableDeclarationStatement(self,
                                          ast: VariableDeclarationStatement):
        e = ast.expr
        if e and has_side_effects(e):
            ast.before_analysis = ast.before_analysis.separate_all()

        # visit expression
        if e:
            self.visit(e)

        # state after declaration
        after = ast.before_analysis.copy()

        # name of variable is already in list
        name = ast.variable_declaration.idf
        assert (after.has(name))

        # make state more precise
        if e and e.privacy_annotation_label():
            after.merge(name, e.privacy_annotation_label())

        ast.after_analysis = after