Beispiel #1
0
 def create_leak_check(self, var_name: str) -> sil.BoolExpression:
     """Create a leak check for all obligation except termination."""
     checks = []
     for obligation in self._obligations:
         if obligation is self._must_terminate_obligation:
             continue
         checks.extend(obligation.create_leak_check(var_name))
     return sil.BigAnd(checks)
Beispiel #2
0
    def _construct_bounded_exhale(
            self, check: Optional[sil.BoolExpression]) -> sil.BoolExpression:
        """Construct bounded obligation exhale.

        :param check: check if measure is positive
        """
        checks = [self._bounded_positive]
        if check is not None:
            checks.append(check)
        return sil.BoolCondExp(sil.BigAnd(checks), self._bounded_acc,
                               self._construct_unbounded_exhale())
Beispiel #3
0
    def _add_caller_leak_check(self) -> None:
        """Add a leak check.

        Check that if callee is not terminating, caller has no
        obligations.
        """
        if obligation_config.disable_call_context_leak_check:
            return
        # MustTerminate leak check.
        must_terminate = self._obligation_manager.must_terminate_obligation
        cthread = self._obligation_info.current_thread_var
        predicate = must_terminate.create_predicate_access(cthread)
        termination_leak_check = sil.CurrentPerm(predicate) == sil.NoPerm()
        # Other obligations leak check.
        reference_name = self._python_method.get_fresh_name('_r')
        leak_check = self._obligation_manager.create_leak_check(reference_name)
        if self._python_method.interface:
            if must_terminate.is_interface_method_terminating(
                    self._python_method.interface_dict):
                exhale = self._obligation_info.caller_measure_map.check(
                    sil.RefVar(self._obligation_info.current_thread_var),
                    sil.RawIntExpression(1))
            else:
                exhale = sil.BigAnd([termination_leak_check, leak_check])
        else:
            # Termination condition.
            tcond = self._obligation_info.create_termination_check(False)
            # Combination.
            exhale = sil.BigOr(
                [tcond,
                 sil.BigAnd([termination_leak_check, leak_check])])
        check = sil.InhaleExhale(sil.TrueLit(), exhale)
        # Translate to Silver.
        node = self.get_function_node()
        position = self._translator.to_position(
            node, self._ctx, rules=rules.OBLIGATION_CALL_LEAK_CHECK_FAIL)
        info = self._translator.to_info(["Caller side leak check"], self._ctx)
        precondition = check.translate(self._translator, self._ctx, position,
                                       info)
        self._obligation_method.append_preconditions([precondition])
Beispiel #4
0
 def _create_level_op(
         self, expr: sil.PermExpression,
         residue_level_var: sil.PermExpression,
         ctx: Context,
         oper: Union[operator.le, operator.lt]) -> sil.BoolExpression:
     obligation = self._obligation_manager.must_release_obligation
     fields = obligation.create_fields_untranslated()
     var = ctx.current_function.create_variable(
         '_r', ctx.module.global_module.classes['object'],
         self.translator, local=False)
     op = oper(self.create_level_call(sil.RefVar(var)), expr)
     for_perms = [sil.ForPerm(var.sil_name, f, op) for f in fields]
     return sil.BigAnd(for_perms + [oper(residue_level_var, expr)])
Beispiel #5
0
 def _create_level_below(self, expr: sil.PermExpression,
                         ctx: Context) -> sil.BoolExpression:
     residue_level_var = sil.PermVar(
         ctx.actual_function.obligation_info.residue_level)
     obligation = self._obligation_manager.must_release_obligation
     fields = obligation.create_fields_untranslated()
     var = ctx.current_function.create_variable(
         '_r',
         ctx.module.global_module.classes[OBJECT_TYPE],
         self._translator.translator,
         local=False)
     op = operator.lt(self.create_level_call(sil.RefVar(var)), expr)
     for_perms = [sil.ForPerm(var.sil_name, f, op) for f in fields]
     return sil.BigAnd(for_perms + [operator.lt(residue_level_var, expr)])
Beispiel #6
0
    def create_termination_check(self,
                                 ignore_measures: bool) -> sil.BoolExpression:
        """Create a check if callee is going to terminate.

        This method is essentially a ``tcond`` macro as defined in
        ``MustTerminate`` documentation.
        """
        disjuncts = []
        for instance in self._get_must_terminate_instances():
            guard = instance.create_guard_expression()
            if ignore_measures:
                disjuncts.append(guard)
            else:
                measure_check = self._check_must_terminate_measure_decrease(
                    instance.obligation_instance.get_measure())
                disjuncts.append(sil.BigAnd([guard, measure_check]))
        return sil.BigOr(disjuncts)
Beispiel #7
0
    def _add_leak_check(self) -> None:
        """Add leak checks to invariant."""
        reference_name = self._ctx.actual_function.get_fresh_name('_r')
        leak_check = self._obligation_manager.create_leak_check(reference_name)
        loop_check_before = sil.BoolVar(
            self._loop_obligation_info.loop_check_before_var)
        termination_flag = sil.BoolVar(
            self._loop_obligation_info.termination_flag_var)

        if not obligation_config.disable_loop_context_leak_check:
            must_terminate = self._obligation_manager.must_terminate_obligation
            predicate = must_terminate.create_predicate_access(
                self._obligation_info.current_thread_var)
            termination_leak_check = sil.CurrentPerm(predicate) == sil.NoPerm()
            loop_cond = self._loop_obligation_info.construct_loop_condition()
            before_loop_leak_check = sil.InhaleExhale(
                sil.TrueLit(),
                sil.Implies(
                    loop_check_before,
                    sil.BigOr([
                        termination_flag,
                        sil.Not(loop_cond),
                        sil.BigAnd([termination_leak_check, leak_check])
                    ])))
            info = self._to_info('Leak check for context.')
            position = self._to_position(
                conversion_rules=rules.OBLIGATION_LOOP_CONTEXT_LEAK_CHECK_FAIL)
            self._obligation_loop.append_invariants([
                before_loop_leak_check.translate(self._translator, self._ctx,
                                                 position, info)
            ])

        if not obligation_config.disable_loop_body_leak_check:
            body_leak_check = sil.InhaleExhale(
                sil.TrueLit(),
                sil.Implies(sil.Not(loop_check_before), leak_check))
            info = self._to_info('Leak check for loop body.')
            position = self._to_position(
                conversion_rules=rules.OBLIGATION_LOOP_BODY_LEAK_CHECK_FAIL)
            self._obligation_loop.append_invariants([
                body_leak_check.translate(self._translator, self._ctx,
                                          position, info)
            ])
Beispiel #8
0
def _create_guard_expression(parts: List[ast.AST]) -> sil.BigAnd:
    """Transform guarding sequence into the guard expression."""
    conjunction = sil.BigAnd(
        [sil.PythonBoolExpression(part) for part in parts])
    return conjunction