Skip to content

Commit f4a3076

Browse files
committed
add three doubly-linked list predicates
This adds three predicates to the C frontend, for the benefit of the CHC encoder. They indicate 1) doubly-linked dynamically allocated null-terminated lists, 2) doubly-linked dynamically allocated cyclic lists, and 3) doubly-linked lists with dynamically allocated inner nodes and head and tail sentinel nodes.
1 parent b06a880 commit f4a3076

File tree

2 files changed

+87
-0
lines changed

2 files changed

+87
-0
lines changed

src/ansi-c/c_typecheck_expr.cpp

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2316,6 +2316,90 @@ exprt c_typecheck_baset::do_special_functions(
23162316

23172317
return std::move(is_list_expr);
23182318
}
2319+
else if(identifier == CPROVER_PREFIX "is_dll")
2320+
{
2321+
if(expr.arguments().size() != 1)
2322+
{
2323+
error().source_location = f_op.source_location();
2324+
error() << "is_dll expects one operand" << eom;
2325+
throw 0;
2326+
}
2327+
2328+
typecheck_function_call_arguments(expr);
2329+
2330+
if(
2331+
expr.arguments()[0].type().id() != ID_pointer ||
2332+
to_pointer_type(expr.arguments()[0].type()).base_type().id() !=
2333+
ID_struct_tag)
2334+
{
2335+
error().source_location = expr.arguments()[0].source_location();
2336+
error() << "is_dll expects a struct-pointer operand" << eom;
2337+
throw 0;
2338+
}
2339+
2340+
predicate_exprt is_dll_expr("is_dll");
2341+
is_dll_expr.operands() = expr.arguments();
2342+
is_dll_expr.add_source_location() = source_location;
2343+
2344+
return std::move(is_dll_expr);
2345+
}
2346+
else if(identifier == CPROVER_PREFIX "is_cyclic_dll")
2347+
{
2348+
if(expr.arguments().size() != 1)
2349+
{
2350+
error().source_location = f_op.source_location();
2351+
error() << "is_cyclic_dll expects one operand" << eom;
2352+
throw 0;
2353+
}
2354+
2355+
typecheck_function_call_arguments(expr);
2356+
2357+
if(
2358+
expr.arguments()[0].type().id() != ID_pointer ||
2359+
to_pointer_type(expr.arguments()[0].type()).base_type().id() !=
2360+
ID_struct_tag)
2361+
{
2362+
error().source_location = expr.arguments()[0].source_location();
2363+
error() << "is_cyclic_dll expects a struct-pointer operand" << eom;
2364+
throw 0;
2365+
}
2366+
2367+
predicate_exprt is_cyclic_dll_expr("is_cyclic_dll");
2368+
is_cyclic_dll_expr.operands() = expr.arguments();
2369+
is_cyclic_dll_expr.add_source_location() = source_location;
2370+
2371+
return std::move(is_cyclic_dll_expr);
2372+
}
2373+
else if(identifier == CPROVER_PREFIX "is_sentinel_dll")
2374+
{
2375+
if(expr.arguments().size() != 2 && expr.arguments().size() != 3)
2376+
{
2377+
error().source_location = f_op.source_location();
2378+
error() << "is_sentinel_dll expects two or three operands" << eom;
2379+
throw 0;
2380+
}
2381+
2382+
typecheck_function_call_arguments(expr);
2383+
2384+
for(const auto &argument : expr.arguments())
2385+
{
2386+
if(
2387+
argument.type().id() != ID_pointer ||
2388+
to_pointer_type(argument.type()).base_type().id() != ID_struct_tag)
2389+
{
2390+
error().source_location = expr.arguments()[0].source_location();
2391+
error() << "is_sentinel_dll_node expects struct-pointer operands"
2392+
<< eom;
2393+
throw 0;
2394+
}
2395+
}
2396+
2397+
predicate_exprt is_sentinel_dll_expr("is_sentinel_dll");
2398+
is_sentinel_dll_expr.operands() = expr.arguments();
2399+
is_sentinel_dll_expr.add_source_location() = source_location;
2400+
2401+
return std::move(is_sentinel_dll_expr);
2402+
}
23192403
else if(identifier == CPROVER_PREFIX "is_cstring")
23202404
{
23212405
if(expr.arguments().size() != 1)

src/ansi-c/cprover_builtin_headers.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ __CPROVER_bool __CPROVER_is_invalid_pointer(const void *);
1212
_Bool __CPROVER_is_zero_string(const void *);
1313
// a singly-linked null-terminated dynamically-allocated list
1414
__CPROVER_bool __CPROVER_is_list();
15+
__CPROVER_bool __CPROVER_is_dll();
16+
__CPROVER_bool __CPROVER_is_cyclic_dll();
17+
__CPROVER_bool __CPROVER_is_sentinel_dll();
1518
__CPROVER_size_t __CPROVER_zero_string_length(const void *);
1619
__CPROVER_bool __CPROVER_is_cstring(const char *);
1720
__CPROVER_size_t __CPROVER_cstrlen(const char *);

0 commit comments

Comments
 (0)