Skip to content

Commit fbbcdb2

Browse files
Add functions to combine property results
Used to update the properties map and to compute the overall result.
1 parent 6516d1f commit fbbcdb2

File tree

2 files changed

+93
-0
lines changed

2 files changed

+93
-0
lines changed

src/goto-checker/properties.cpp

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

src/goto-checker/properties.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,4 +90,8 @@ int result_to_exit_code(resultt result);
9090
std::size_t
9191
count_properties(const propertiest &, property_statust);
9292

93+
property_resultt &operator|=(property_resultt &, property_resultt const &);
94+
property_resultt &operator&=(property_resultt &, property_resultt const &);
95+
resultt determine_result(const propertiest &properties);
96+
9397
#endif // CPROVER_GOTO_CHECKER_PROPERTIES_H

0 commit comments

Comments
 (0)