Skip to content

Commit e196ac5

Browse files
Add functions to combine property results
Used to update the properties map and to compute the overall result.
1 parent 55da8d3 commit e196ac5

File tree

2 files changed

+90
-0
lines changed

2 files changed

+90
-0
lines changed

src/goto-checker/properties.cpp

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,3 +149,89 @@ bool has_properties_to_check(const propertiest &properties)
149149
}
150150
return false;
151151
}
152+
153+
/// Update with the preference order
154+
/// 1. old non-UNKNOWN/non-NOT_REACHED result
155+
/// 2. new non-UNKNOWN/non-NOT_REACHED result
156+
/// 3. UNKNOWN
157+
/// 4. NOT_REACHED
158+
/// Suitable for updating property results
159+
property_resultt &operator|=(property_resultt &a, property_resultt const &b)
160+
{
161+
// non-monotonic use is likely a bug
162+
PRECONDITION(
163+
a == property_resultt::NOT_REACHED ||
164+
(a == property_resultt::UNKNOWN && b != property_resultt::NOT_REACHED) ||
165+
a == b);
166+
switch(a)
167+
{
168+
case property_resultt::NOT_REACHED:
169+
case property_resultt::UNKNOWN:
170+
a = b;
171+
return a;
172+
case property_resultt::ERROR:
173+
case property_resultt::PASS:
174+
case property_resultt::NOT_REACHABLE:
175+
case property_resultt::FAIL:
176+
return a;
177+
}
178+
UNREACHABLE;
179+
}
180+
181+
/// Update with the preference order
182+
/// 1. ERROR
183+
/// 2. FAIL
184+
/// 3. UNKNOWN
185+
/// 4. NOT_REACHED
186+
/// 5. NOT_REACHABLE
187+
/// 6. PASS
188+
/// Suitable for computing overall results
189+
property_resultt &operator&=(property_resultt &a, property_resultt const &b)
190+
{
191+
switch(a)
192+
{
193+
case property_resultt::ERROR:
194+
a = b;
195+
return a;
196+
case property_resultt::FAIL:
197+
a = (b == property_resultt::ERROR ? b : a);
198+
return a;
199+
case property_resultt::UNKNOWN:
200+
a = (b == property_resultt::ERROR || b == property_resultt::FAIL ? b : a);
201+
return a;
202+
case property_resultt::NOT_REACHED:
203+
a = (b != property_resultt::PASS && b != property_resultt::NOT_REACHABLE? b : a);
204+
return a;
205+
case property_resultt::NOT_REACHABLE:
206+
a = (b != property_resultt::PASS ? b : a);
207+
return a;
208+
case property_resultt::PASS:
209+
a = (b == property_resultt::PASS ? a : b);
210+
return a;
211+
}
212+
UNREACHABLE;
213+
}
214+
215+
/// Determines the overall result corresponding from the given properties
216+
/// That is PASS if all properties are PASS or NOT_REACHED,
217+
/// FAIL if at least one property is FAIL and no property is ERROR,
218+
/// UNKNOWN if no property is FAIL or ERROR and
219+
/// at least one property is UNKNOWN,
220+
/// ERROR if at least one property is error.
221+
resultt determine_result(const propertiest &properties)
222+
{
223+
property_resultt result = property_resultt::PASS;
224+
for(const auto &property_pair : properties)
225+
{
226+
result &= property_pair.second.result;
227+
}
228+
// If we haven't reached anything or nothing is reachable
229+
// then overall it's still a PASS.
230+
if(
231+
result == property_resultt::NOT_REACHED ||
232+
result == property_resultt::NOT_REACHABLE)
233+
{
234+
result = property_resultt::PASS;
235+
}
236+
return static_cast<resultt>(result);
237+
}

src/goto-checker/properties.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,4 +86,8 @@ count_properties(const propertiest &properties, property_resultt result);
8686

8787
bool has_properties_to_check(const propertiest &properties);
8888

89+
property_resultt &operator|=(property_resultt &, property_resultt const &);
90+
property_resultt &operator&=(property_resultt &, property_resultt const &);
91+
resultt determine_result(const propertiest &properties);
92+
8993
#endif // CPROVER_GOTO_CHECKER_PROPERTIES_H

0 commit comments

Comments
 (0)