Skip to content

Commit 515f050

Browse files
committed
Pass the condition to the invariant_failedt constructor.
1 parent bf6dd9e commit 515f050

File tree

2 files changed

+51
-32
lines changed

2 files changed

+51
-32
lines changed

src/util/invariant.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ Author: Martin Brain, [email protected]
88

99
#include "invariant.h"
1010

11-
#include "util/freer.h"
11+
#include "freer.h"
1212

1313
#include <memory>
1414
#include <string>
@@ -121,13 +121,14 @@ std::string invariant_failedt::get_invariant_failed_message(
121121
const std::string &function,
122122
int line,
123123
const std::string &backtrace,
124-
const std::string &reason)
124+
const std::string &reason) const
125125
{
126126
std::ostringstream out;
127127
out << "Invariant check failed\n"
128128
<< "File " << file
129129
<< " function " << function
130130
<< " line " << line << '\n'
131+
<< "Condition: " << condition << '\n'
131132
<< "Reason: " << reason
132133
<< "\nBacktrace:\n"
133134
<< backtrace << '\n';

src/util/invariant.h

Lines changed: 48 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -72,41 +72,43 @@ Author: Martin Brain, [email protected]
7272
/// family of macros, allowing constructs like
7373
/// `INVARIANT(x==y, my_invariantt, (T1)actual1, (T2)actual2, ...)`
7474
///
75-
class invariant_failedt: public std::logic_error
75+
class invariant_failedt
7676
{
7777
private:
78-
std::string get_invariant_failed_message(
79-
const std::string &file,
80-
const std::string &function,
81-
int line,
82-
const std::string &backtrace,
83-
const std::string &reason);
78+
std::string get_invariant_failed_message(
79+
const std::string &file,
80+
const std::string &function,
81+
int line,
82+
const std::string &backtrace,
83+
const std::string &reason) const;
8484

8585
public:
8686
const std::string file;
8787
const std::string function;
8888
const int line;
8989
const std::string backtrace;
9090
const std::string reason;
91+
const std::string condition;
92+
93+
std::string what() const noexcept
94+
{
95+
return get_invariant_failed_message(
96+
file, function, line, backtrace, reason);
97+
};
9198

9299
invariant_failedt(
93100
const std::string &_file,
94101
const std::string &_function,
95102
int _line,
96103
const std::string &_backtrace,
97-
const std::string &_reason):
98-
logic_error(
99-
get_invariant_failed_message(
100-
_file,
101-
_function,
102-
_line,
103-
_backtrace,
104-
_reason)),
105-
file(_file),
106-
function(_function),
107-
line(_line),
108-
backtrace(_backtrace),
109-
reason(_reason)
104+
const std::string &_reason,
105+
const std::string &_condition)
106+
: file(_file),
107+
function(_function),
108+
line(_line),
109+
backtrace(_backtrace),
110+
reason(_reason),
111+
condition(_condition)
110112
{
111113
}
112114
};
@@ -149,9 +151,10 @@ void report_exception_to_stderr(const invariant_failedt &);
149151
/// \param file : C string giving the name of the file.
150152
/// \param function : C string giving the name of the function.
151153
/// \param line : The line number of the invariant
154+
/// \param condition : the condition this invariant is checking.
152155
/// \param params : (variadic) parameters to forward to ET's constructor
153156
/// its backtrace member will be set before it is used.
154-
template<class ET, typename ...Params>
157+
template <class ET, typename... Params>
155158
#ifdef __GNUC__
156159
__attribute__((noreturn))
157160
#endif
@@ -160,10 +163,17 @@ invariant_violated_structured(
160163
const std::string &file,
161164
const std::string &function,
162165
const int line,
166+
const std::string &condition,
163167
Params &&... params)
164168
{
165169
std::string backtrace=get_backtrace();
166-
ET to_throw(file, function, line, backtrace, std::forward<Params>(params)...);
170+
ET to_throw(
171+
file,
172+
function,
173+
line,
174+
backtrace,
175+
std::forward<Params>(params)...,
176+
condition);
167177
// We now have a structured exception ready to use;
168178
// in future this is the place to put a 'throw'.
169179
report_exception_to_stderr(to_throw);
@@ -177,20 +187,20 @@ invariant_violated_structured(
177187
/// \param function : C string giving the name of the function.
178188
/// \param line : The line number of the invariant
179189
/// \param reason : brief description of the invariant violation.
190+
/// \param condition : the condition this invariant is checking.
180191
#ifdef __GNUC__
181192
__attribute__((noreturn))
182193
#endif
183-
inline void invariant_violated_string(
194+
inline void
195+
invariant_violated_string(
184196
const std::string &file,
185197
const std::string &function,
186198
const int line,
187-
const std::string &reason)
199+
const std::string &reason,
200+
const std::string &condition)
188201
{
189202
invariant_violated_structured<invariant_failedt>(
190-
file,
191-
function,
192-
line,
193-
reason);
203+
file, function, line, condition, reason);
194204
}
195205

196206
// These require a trailing semicolon by the user, such that INVARIANT
@@ -207,15 +217,23 @@ inline void invariant_violated_string(
207217
{ \
208218
if(!(CONDITION)) \
209219
invariant_violated_string( \
210-
__FILE__, __this_function__, __LINE__, (REASON)); /* NOLINT */ \
220+
__FILE__, \
221+
__this_function__, \
222+
__LINE__, \
223+
(REASON), \
224+
#CONDITION); /* NOLINT */ \
211225
} while(false)
212226

213227
#define INVARIANT_STRUCTURED(CONDITION, TYPENAME, ...) \
214228
do /* NOLINT */ \
215229
{ \
216230
if(!(CONDITION)) \
217231
invariant_violated_structured<TYPENAME>( \
218-
__FILE__, __this_function__, __LINE__, __VA_ARGS__); /* NOLINT */ \
232+
__FILE__, \
233+
__this_function__, \
234+
__LINE__, \
235+
__VA_ARGS__, \
236+
#CONDITION); /* NOLINT */ \
219237
} while(false)
220238

221239
#endif // End CPROVER_DO_NOT_CHECK / CPROVER_ASSERT / ... if block

0 commit comments

Comments
 (0)