9#ifndef CPROVER_UTIL_INVARIANT_H
10#define CPROVER_UTIL_INVARIANT_H
112 const std::string
file;
172#define CBMC_NORETURN __attribute((noreturn))
173#elif defined(_MSC_VER)
174#define CBMC_NORETURN __declspec(noreturn)
175#elif __cplusplus >= 201703L
176#define CBMC_NORETURN [[noreturn]]
181#if defined(CPROVER_INVARIANT_CPROVER_ASSERT)
183#define INVARIANT(CONDITION, REASON) \
184 __CPROVER_assert((CONDITION), "Invariant : " REASON)
185#define INVARIANT_WITH_DIAGNOSTICS(CONDITION, REASON, ...) \
186 __CPROVER_assert((CONDITION), "Invariant : " REASON)
188#define INVARIANT_STRUCTURED(CONDITION, TYPENAME, ...) \
189 INVARIANT(CONDITION, "")
191#elif defined(CPROVER_INVARIANT_DO_NOT_CHECK)
196#define INVARIANT(CONDITION, REASON) \
200#define INVARIANT_WITH_DIAGNOSTICS(CONDITION, REASON, ...) \
204#define INVARIANT_STRUCTURED(CONDITION, TYPENAME, ...) do {} while(false)
206#elif defined(CPROVER_INVARIANT_ASSERT)
210#define INVARIANT(CONDITION, REASON) assert((CONDITION) && ((REASON), true))
211#define INVARIANT_WITH_DIAGNOSTICS(CONDITION, REASON, ...) \
212 assert((CONDITION) && ((REASON), true))
214#define INVARIANT_STRUCTURED(CONDITION, TYPENAME, ...) assert((CONDITION))
236template <
class ET,
typename...
Params>
238 typename std::enable_if<std::is_base_of<invariant_failedt, ET>::value>::type
240 const std::string &file,
241 const std::string &function,
243 const std::string &condition,
253 std::forward<Params>(params)...);
276 const std::string &file,
277 const std::string &function,
279 const std::string &condition,
280 const std::string &reason)
283 file, function, line, condition, reason);
303 "to avoid unintended strangeness, diagnostics_helpert needs to be "
304 "specialised for each diagnostic type");
311template <std::
size_t N>
351 typename std::remove_cv<typename std::remove_reference<T>::type>::type>
::
359template <
typename T,
typename...
Ts>
369 std::ostringstream out;
370 out <<
"\n<< EXTRA DIAGNOSTICS >>";
372 out <<
"\n<< END EXTRA DIAGNOSTICS >>";
380 const std::string &file,
381 const std::string &function,
384 std::string condition,
396#define EXPAND_MACRO(x) x
402#define CURRENT_FUNCTION_NAME __FUNCTION__
404#define CURRENT_FUNCTION_NAME __func__
407#define INVARIANT_STRUCTURED(CONDITION, TYPENAME, ...) \
411 invariant_violated_structured<TYPENAME>( \
413 CURRENT_FUNCTION_NAME, \
407#define INVARIANT_STRUCTURED(CONDITION, TYPENAME, ...) \ …
423#define INVARIANT(CONDITION, REASON) \
428 invariant_violated_string( \
429 __FILE__, CURRENT_FUNCTION_NAME, __LINE__, #CONDITION, REASON); \
423#define INVARIANT(CONDITION, REASON) \ …
437#define INVARIANT_WITH_DIAGNOSTICS(CONDITION, REASON, ...) \
442 report_invariant_failure( \
444 CURRENT_FUNCTION_NAME, \
437#define INVARIANT_WITH_DIAGNOSTICS(CONDITION, REASON, ...) \ …
463#define PRECONDITION(CONDITION) INVARIANT(CONDITION, "Precondition")
464#define PRECONDITION_WITH_DIAGNOSTICS(CONDITION, ...) \
465 INVARIANT_WITH_DIAGNOSTICS(CONDITION, "Precondition", __VA_ARGS__)
464#define PRECONDITION_WITH_DIAGNOSTICS(CONDITION, ...) \ …
467#define PRECONDITION_STRUCTURED(CONDITION, TYPENAME, ...) \
468 EXPAND_MACRO(INVARIANT_STRUCTURED(CONDITION, TYPENAME, __VA_ARGS__))
467#define PRECONDITION_STRUCTURED(CONDITION, TYPENAME, ...) \ …
479#define POSTCONDITION(CONDITION) INVARIANT(CONDITION, "Postcondition")
480#define POSTCONDITION_WITH_DIAGNOSTICS(CONDITION, ...) \
481 INVARIANT_WITH_DIAGNOSTICS(CONDITION, "Postcondition", __VA_ARGS__)
480#define POSTCONDITION_WITH_DIAGNOSTICS(CONDITION, ...) \ …
483#define POSTCONDITION_STRUCTURED(CONDITION, TYPENAME, ...) \
484 EXPAND_MACRO(INVARIANT_STRUCTURED(CONDITION, TYPENAME, __VA_ARGS__))
483#define POSTCONDITION_STRUCTURED(CONDITION, TYPENAME, ...) \ …
495#define CHECK_RETURN(CONDITION) INVARIANT(CONDITION, "Check return value")
496#define CHECK_RETURN_WITH_DIAGNOSTICS(CONDITION, ...) \
497 INVARIANT_WITH_DIAGNOSTICS(CONDITION, "Check return value", __VA_ARGS__)
496#define CHECK_RETURN_WITH_DIAGNOSTICS(CONDITION, ...) \ …
499#define CHECK_RETURN_STRUCTURED(CONDITION, TYPENAME, ...) \
500 EXPAND_MACRO(INVARIANT_STRUCTURED(CONDITION, TYPENAME, __VA_ARGS__))
499#define CHECK_RETURN_STRUCTURED(CONDITION, TYPENAME, ...) \ …
506# define UNREACHABLE \
509 INVARIANT(false, "Unreachable"); \
510 __builtin_unreachable(); \
512# define UNREACHABLE_BECAUSE(REASON) \
515 INVARIANT(false, REASON); \
516 __builtin_unreachable(); \
518# define UNREACHABLE_STRUCTURED(TYPENAME, ...) \
521 EXPAND_MACRO(INVARIANT_STRUCTURED(false, TYPENAME, __VA_ARGS__)); \
522 __builtin_unreachable(); \
525# define UNREACHABLE INVARIANT(false, "Unreachable")
526# define UNREACHABLE_BECAUSE(REASON) INVARIANT(false, REASON)
527# define UNREACHABLE_STRUCTURED(TYPENAME, ...) \
528 EXPAND_MACRO(INVARIANT_STRUCTURED(false, TYPENAME, __VA_ARGS__))
527# define UNREACHABLE_STRUCTURED(TYPENAME, ...) \ …
534#define DATA_INVARIANT(CONDITION, REASON) INVARIANT(CONDITION, REASON)
535#define DATA_INVARIANT_WITH_DIAGNOSTICS(CONDITION, REASON, ...) \
536 INVARIANT_WITH_DIAGNOSTICS(CONDITION, REASON, __VA_ARGS__)
535#define DATA_INVARIANT_WITH_DIAGNOSTICS(CONDITION, REASON, ...) \ …
538#define DATA_INVARIANT_STRUCTURED(CONDITION, TYPENAME, ...) \
539 EXPAND_MACRO(INVARIANT_STRUCTURED(CONDITION, TYPENAME, __VA_ARGS__))
538#define DATA_INVARIANT_STRUCTURED(CONDITION, TYPENAME, ...) \ …
542# define UNIMPLEMENTED_FEATURE(FEATURE) \
545 INVARIANT(false, std::string{"Reached unimplemented "} + (FEATURE)); \
546 __builtin_unreachable(); \
549# define UNIMPLEMENTED_FEATURE(FEATURE) \
550 INVARIANT(false, std::string{"Reached unimplemented "} + (FEATURE))
549# define UNIMPLEMENTED_FEATURE(FEATURE) \ …
557#define TODO INVARIANT(false, "Todo")
558#define UNIMPLEMENTED INVARIANT(false, "Unimplemented")
559#define UNHANDLED_CASE INVARIANT(false, "Unhandled case")
ait supplies three of the four components needed: an abstract interpreter (in this case handling func...
A logic error, augmented with a distinguished field to hold a backtrace.
const std::string backtrace
const std::string condition
virtual ~invariant_failedt()=default
const std::string function
virtual std::string what() const noexcept
A class that includes diagnostic information related to an invariant violation.
virtual std::string what() const noexcept
const std::string diagnostics
void write_rest_diagnostics(std::ostream &)
std::string diagnostic_as_string(T &&val)
std::string assemble_diagnostics()
void report_exception_to_stderr(const invariant_failedt &)
Dump exception report to stderr.
std::string get_backtrace()
Returns a backtrace.
void report_invariant_failure(const std::string &file, const std::string &function, int line, std::string reason, std::string condition, Diagnostics &&... diagnostics)
This is a wrapper function, used by the macro 'INVARIANT_WITH_DIAGNOSTICS'.
void invariant_violated_string(const std::string &file, const std::string &function, const int line, const std::string &condition, const std::string &reason)
This is a wrapper function used by the macro 'INVARIANT(CONDITION, REASON)'.
void print_backtrace(std::ostream &out)
Prints a back trace to 'out'.
bool cbmc_invariants_should_throw
Set this to true to cause invariants to throw a C++ exception rather than abort the program.
std::enable_if< std::is_base_of< invariant_failedt, ET >::value >::type invariant_violated_structured(const std::string &file, const std::string &function, const int line, const std::string &condition, Params &&... params)
This function is the backbone of all the invariant types.
Helper to enable invariant throwing as above bounded to an object lifetime:
~cbmc_invariants_should_throwt()
cbmc_invariants_should_throwt()
static std::string diagnostics_as_string(const char *string)
static std::string diagnostics_as_string(const char(&string)[N])
static std::string diagnostics_as_string(std::string string)
Helper to give us some diagnostic in a usable form on assertion failure.
static std::string diagnostics_as_string(const T &)