diff --git a/src/plugins/e-acsl/share/e-acsl/instrumentation_model/e_acsl_assert.c b/src/plugins/e-acsl/share/e-acsl/instrumentation_model/e_acsl_assert.c index 076a44f350f99e02a5e7032745d9e15219312345..e6a105f2ecce9df29d2c651a33d6fd57c919fed1 100644 --- a/src/plugins/e-acsl/share/e-acsl/instrumentation_model/e_acsl_assert.c +++ b/src/plugins/e-acsl/share/e-acsl/instrumentation_model/e_acsl_assert.c @@ -36,8 +36,8 @@ int eacsl_runtime_sound_verdict = 1; #ifndef E_ACSL_EXTERNAL_ASSERT /*! \brief Default implementation of E-ACSL runtime assertions */ -void eacsl_runtime_assert(int predicate, const char *kind, const char *fct, - const char *pred_txt, const char * file, int line) { +void eacsl_runtime_assert(int predicate, int blocking, const char *kind, + const char *fct, const char *pred_txt, const char * file, int line) { if (eacsl_runtime_sound_verdict) { if (! predicate) { STDERR("%s: In function '%s'\n" @@ -45,13 +45,15 @@ void eacsl_runtime_assert(int predicate, const char *kind, const char *fct, "\tThe failing predicate is:\n" "\t%s.\n", file, fct, file, line, kind, pred_txt); + if (blocking) { #ifndef E_ACSL_NO_ASSERT_FAIL /* Do fail on assertions */ #ifdef E_ACSL_FAIL_EXITCODE /* Fail by exit with a given code */ - exit(E_ACSL_FAIL_EXITCODE); + exit(E_ACSL_FAIL_EXITCODE); #else - raise_abort(file, line); /* Raise abort signal */ + raise_abort(file, line); /* Raise abort signal */ #endif #endif + } } } else STDERR("%s: In function '%s'\n" diff --git a/src/plugins/e-acsl/share/e-acsl/instrumentation_model/e_acsl_assert.h b/src/plugins/e-acsl/share/e-acsl/instrumentation_model/e_acsl_assert.h index 46e8fe3a6ad1018564f6a782f6d6c8138e9a2011..6cc1a782efda5697df633cd2724aaf60b78eaf92 100644 --- a/src/plugins/e-acsl/share/e-acsl/instrumentation_model/e_acsl_assert.h +++ b/src/plugins/e-acsl/share/e-acsl/instrumentation_model/e_acsl_assert.h @@ -41,15 +41,23 @@ extern int eacsl_runtime_sound_verdict; /*! \brief Runtime assertion verifying a given predicate * \param pred integer code of a predicate - * \param kind C string representing a kind an annotation (e.g., "Assertion") + * \param blocking integer representing if the assertion is blocking or not + * \param kind C string representing a kind of annotation (e.g., "Assertion") * \param fct * \param pred_txt stringified predicate * \param file un-instrumented file of predicate placement * \param line line of predicate placement in the un-instrumented file */ -/*@ requires pred != 0; - @ assigns \nothing; */ -void eacsl_runtime_assert(int pred, const char *kind, const char *fct, - const char *pred_txt, const char * file, int line) +/*@ assigns \nothing; + @ behavior blocking: + @ assumes blocking != 0; + @ requires pred != 0; + @ behavior non_blocking: + @ assumes blocking == 0; + @ check requires pred != 0; + @ complete behaviors; + @ disjoint behaviors; */ +void eacsl_runtime_assert(int pred, int blocking, const char *kind, + const char *fct, const char *pred_txt, const char * file, int line) __attribute__((FC_BUILTIN)); #endif // E_ACSL_ASSERT_H diff --git a/src/plugins/e-acsl/src/code_generator/smart_stmt.ml b/src/plugins/e-acsl/src/code_generator/smart_stmt.ml index c126fe01e0ba9fbff3662f5e8bd225919a71245a..1cc37e8113c2e018354194b310ba91c89ce61a85 100644 --- a/src/plugins/e-acsl/src/code_generator/smart_stmt.ml +++ b/src/plugins/e-acsl/src/code_generator/smart_stmt.ml @@ -177,25 +177,33 @@ let mark_readonly vi = let loc = vi.vdecl in rtl_call ~loc "mark_readonly" [ Cil.evar ~loc vi ] -let runtime_check_with_msg ~loc msg kind kf e = +let runtime_check_with_msg ~loc msg ~pred_kind kind kf e = + let blocking = + match pred_kind with + | Assert -> Cil.one ~loc + | Check -> Cil.zero ~loc + | Admit -> + Options.fatal "No runtime check should be generated for 'admit' clauses" + in let file = (fst loc).Filepath.pos_path in let line = (fst loc).Filepath.pos_lnum in rtl_call ~loc "assert" [ e; + blocking; kind_to_string loc kind; Cil.mkString ~loc (Functions.RTL.get_original_name kf); Cil.mkString ~loc msg; Cil.mkString ~loc (Filepath.Normalized.to_pretty_string file); Cil.integer loc line ] -let runtime_check kind kf e p = +let runtime_check ~pred_kind kind kf e p = let loc = p.pred_loc in let msg = Kernel.Unicode.without_unicode (Format.asprintf "%a@?" Printer.pp_predicate) p in - runtime_check_with_msg ~loc msg kind kf e + runtime_check_with_msg ~loc msg ~pred_kind kind kf e (* Local Variables: diff --git a/src/plugins/e-acsl/src/code_generator/smart_stmt.mli b/src/plugins/e-acsl/src/code_generator/smart_stmt.mli index abd797824e97d0e018a076089db1919abbab50cc..c56404a5a7120a2b752aacca94471f0c9f1ff758 100644 --- a/src/plugins/e-acsl/src/code_generator/smart_stmt.mli +++ b/src/plugins/e-acsl/src/code_generator/smart_stmt.mli @@ -107,19 +107,23 @@ type annotation_kind = | RTE val runtime_check: - annotation_kind -> kernel_function -> exp -> predicate -> stmt -(** [runtime_check kind kf e p] generates a runtime check for predicate [p] - by building a call to [__e_acsl_assert]. [e] (or [!e] if [reverse] is set to - [true]) is the C translation of [p], [kf] is the current kernel_function and - [kind] is the annotation kind of [p]. *) + pred_kind:predicate_kind -> annotation_kind -> kernel_function -> exp -> + predicate -> stmt +(** [runtime_check ~pred_kind kind kf e p] generates a runtime check for + predicate [p] by building a call to [__e_acsl_assert]. [e] (or [!e] if + [reverse] is set to [true]) is the C translation of [p], [kf] is the current + kernel_function, [kind] is the annotation kind of [p] and [pred_kind] + indicates if the assert should be blocking or not. *) val runtime_check_with_msg: - loc:location -> string -> annotation_kind -> kernel_function -> exp -> stmt -(** [runtime_check_with_msg kind kf e msg] generates a runtime check for [e] - (or [!e] if [reverse] is [true]) by building a call to [__e_acsl_assert]. - [msg] is the message printed if the runtime check fails. [loc] is the - location printed in the message if the runtime check fails. [kf] is the - current kernel_function and [kind] is the annotation kind of [p]. *) + loc:location -> string -> pred_kind:predicate_kind -> annotation_kind -> + kernel_function -> exp -> stmt +(** [runtime_check_with_msg ~loc msg ~pred_kind kind kf e] generates a runtime + check for [e] (or [!e] if [reverse] is [true]) by building a call to + [__e_acsl_assert]. [msg] is the message printed if the runtime check fails. + [loc] is the location printed in the message if the runtime check fails. + [kf] is the current kernel_function, [kind] is the annotation kind of [p] + and [pred_kind] indicates if the assert should be blocking or not. *) (* Local Variables: