예제 #1
0
 def _add_additional_preconditions(self) -> None:
     """Add preconditions about current thread and caller measures."""
     preconditions = []
     if not obligation_config.disable_all:
         cthread_var = self._obligation_info.current_thread_var
         cthread = sil.RefVar(cthread_var)
         preconditions.append(cthread != None)
     position = self._position
     if (self._is_body_native_silver()
             and not obligation_config.disable_termination_check):
         # Add obligations described in interface_dict.
         assert self._python_method.interface
         for obligation in self._obligation_manager.obligations:
             preconditions.extend(
                 obligation.generate_axiomatized_preconditions(
                     self._obligation_info,
                     self._python_method.interface_dict))
         func_node = self.get_function_node()
         position = self._translator.to_position(
             func_node,
             self._ctx,
             rules=rules.OBLIGATION_CALL_LEAK_CHECK_FAIL)
     translated = [
         precondition.translate(self._translator, self._ctx, position,
                                self._info)
         for precondition in preconditions
     ]
     if not obligation_config.disable_all:
         translated.append(
             self._translator.var_type_check(cthread_var.sil_name,
                                             cthread_var.type,
                                             self._position, self._ctx))
     self._obligation_method.prepend_precondition(translated)
     self._obligation_method.append_preconditions(
         self._obligation_info.get_additional_preconditions())
예제 #2
0
 def generate_axiomatized_preconditions(
         self, obligation_info: 'PythonMethodObligationInfo',
         interface_dict: Dict[str, Any]) -> List[sil.BoolExpression]:
     """Add ``MustTerminate(1)`` to axiomatic method precondition."""
     if self.is_interface_method_terminating(interface_dict):
         cthread = sil.RefVar(obligation_info.current_thread_var)
         check = obligation_info.caller_measure_map.check(
             cthread, sil.RawIntExpression(1))
         return [check]
     else:
         return []
예제 #3
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)])
예제 #4
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)])
예제 #5
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])
예제 #6
0
 def construct_loop_condition(self) -> sil.BoolExpression:
     """Construct loop condition."""
     if isinstance(self.node, ast.While):
         return sil.PythonBoolExpression(self.node.test)
     else:
         return sil.RefVar(self.iteration_err_var) == None  # noqa: E711
예제 #7
0
 def _check_must_terminate_measure_decrease(
         self, measure: sil.IntExpression) -> sil.BoolExpression:
     return self.loop_measure_map.check(sil.RefVar(self.current_thread_var),
                                        measure)
예제 #8
0
 def get_target(self) -> sil.RefExpression:
     return sil.RefVar(self._target)
예제 #9
0
def _create_predicate_access(cthread: PythonVar) -> sil.PredicateAccess:
    """Create a predicate access expression."""
    return sil.PredicateAccess(_PREDICATE_NAME, sil.RefVar(cthread))
예제 #10
0
 def _translate_level(self, node: ast.Call) -> sil.PermExpression:
     """Translate a call to ``Level``."""
     assert len(node.args) == 1
     arg = sil.RefVar(node.args[0])
     return self.create_level_call(arg)