72
72
// / family of macros, allowing constructs like
73
73
// / `INVARIANT(x==y, my_invariantt, (T1)actual1, (T2)actual2, ...)`
74
74
// /
75
- class invariant_failedt : public std ::logic_error
75
+ class invariant_failedt
76
76
{
77
77
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 ;
84
84
85
85
public:
86
86
const std::string file;
87
87
const std::string function;
88
88
const int line;
89
89
const std::string backtrace;
90
90
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
+ };
91
98
92
99
invariant_failedt (
93
100
const std::string &_file,
94
101
const std::string &_function,
95
102
int _line,
96
103
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)
110
112
{
111
113
}
112
114
};
@@ -149,9 +151,10 @@ void report_exception_to_stderr(const invariant_failedt &);
149
151
// / \param file : C string giving the name of the file.
150
152
// / \param function : C string giving the name of the function.
151
153
// / \param line : The line number of the invariant
154
+ // / \param condition : the condition this invariant is checking.
152
155
// / \param params : (variadic) parameters to forward to ET's constructor
153
156
// / its backtrace member will be set before it is used.
154
- template <class ET , typename ...Params>
157
+ template <class ET , typename ... Params>
155
158
#ifdef __GNUC__
156
159
__attribute__ ((noreturn))
157
160
#endif
@@ -160,10 +163,17 @@ invariant_violated_structured(
160
163
const std::string &file,
161
164
const std::string &function,
162
165
const int line,
166
+ const std::string &condition,
163
167
Params &&... params)
164
168
{
165
169
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);
167
177
// We now have a structured exception ready to use;
168
178
// in future this is the place to put a 'throw'.
169
179
report_exception_to_stderr (to_throw);
@@ -177,20 +187,20 @@ invariant_violated_structured(
177
187
// / \param function : C string giving the name of the function.
178
188
// / \param line : The line number of the invariant
179
189
// / \param reason : brief description of the invariant violation.
190
+ // / \param condition : the condition this invariant is checking.
180
191
#ifdef __GNUC__
181
192
__attribute__ ((noreturn))
182
193
#endif
183
- inline void invariant_violated_string (
194
+ inline void
195
+ invariant_violated_string (
184
196
const std::string &file,
185
197
const std::string &function,
186
198
const int line,
187
- const std::string &reason)
199
+ const std::string &reason,
200
+ const std::string &condition)
188
201
{
189
202
invariant_violated_structured<invariant_failedt>(
190
- file,
191
- function,
192
- line,
193
- reason);
203
+ file, function, line, condition, reason);
194
204
}
195
205
196
206
// These require a trailing semicolon by the user, such that INVARIANT
@@ -207,15 +217,23 @@ inline void invariant_violated_string(
207
217
{ \
208
218
if (!(CONDITION)) \
209
219
invariant_violated_string ( \
210
- __FILE__, __this_function__, __LINE__, (REASON)); /* NOLINT */ \
220
+ __FILE__, \
221
+ __this_function__, \
222
+ __LINE__, \
223
+ (REASON), \
224
+ #CONDITION); /* NOLINT */ \
211
225
} while (false )
212
226
213
227
#define INVARIANT_STRUCTURED (CONDITION, TYPENAME, ...) \
214
228
do /* NOLINT */ \
215
229
{ \
216
230
if (!(CONDITION)) \
217
231
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 */ \
219
237
} while (false )
220
238
221
239
#endif // End CPROVER_DO_NOT_CHECK / CPROVER_ASSERT / ... if block
0 commit comments