mirror of
https://github.com/revng/revng
synced 2026-06-21 14:07:57 +00:00
a0f4e0bb41
A set of assertion-related functions has been introduced: * `revng_abort(message)`: aborts, in release builds too. * `revng_check(what, message)`: asserts `what`, in release builds too. Also emits a `__builtin_assume`, that can lead to additional optimizations in clang. * `revng_unreahcable(message)`: identical to `revng_abort`, but in release builds emits `__built_unreachable`. * `revng_assert(what, message)`: asserts in debug builds, otherwise emits `sizeof(what)` (to suppress unused variable warnings) and `__builtin_assume`. The adoption of these function has the following benefits: * Nice stack traces. * The developer can choose to enforce an `assert` (or an `unreachable`) at release-time too by using `check`/`abort`. * Most warnings about unused variables in release mode should be gone. * When using clang, the `assert`s become `assume`s, which might enable additional optimizations (with no run-time costs). * The `assert(Condition && "Reason")` trick is no longer needed, we now have a proper argument.
56 lines
1.4 KiB
C++
56 lines
1.4 KiB
C++
/// \file revng-assert.cpp
|
|
/// \brief Implementation of the various functions to assert and abort.
|
|
|
|
// Standard includes
|
|
#include <iostream>
|
|
|
|
// LLVM includes
|
|
#include "llvm/Support/raw_os_ostream.h"
|
|
#include "llvm/Support/Signals.h"
|
|
|
|
// Local includes
|
|
#include "revng-assert.h"
|
|
|
|
static void print_stack_trace() {
|
|
llvm::raw_os_ostream Output(std::cout);
|
|
std::cout << "\n";
|
|
llvm::sys::PrintStackTrace(Output);
|
|
}
|
|
|
|
[[noreturn]] static void terminate(void) {
|
|
print_stack_trace();
|
|
abort();
|
|
}
|
|
|
|
static void report(const char *Type,
|
|
const char *File,
|
|
unsigned Line,
|
|
const char *What) {
|
|
fprintf(stderr, "%s at %s:%d: %s\n", Type, File, Line, What);
|
|
}
|
|
|
|
void revng_assert_fail(const char *AssertionBody,
|
|
const char *Message,
|
|
const char *File,
|
|
unsigned Line) {
|
|
report("Assertion failed", File, Line, Message);
|
|
fprintf(stderr, "%s\n", AssertionBody);
|
|
terminate();
|
|
}
|
|
|
|
void revng_check_fail(const char *CheckBody,
|
|
const char *Message,
|
|
const char *File,
|
|
unsigned Line) {
|
|
report("Check failed", File, Line, Message);
|
|
fprintf(stderr, "%s\n", CheckBody);
|
|
terminate();
|
|
}
|
|
|
|
void revng_do_abort(const char *Message,
|
|
const char *File,
|
|
unsigned Line) {
|
|
report("Abort", File, Line, Message);
|
|
terminate();
|
|
}
|