-
Notifications
You must be signed in to change notification settings - Fork 273
Prevent empty arrays from being passed to the solver #1634
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Prevent empty arrays from being passed to the solver #1634
Conversation
|
What do you expect to get as a model for a symbol of type array which has size 0 ?
What would be the result in that case? SAT/UNSAT/ERROR ? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a Jira issue for that?
Can we create a regression test?
expr.depth_begin(), | ||
expr.depth_end(), | ||
[] (const exprt &e) | ||
{ return e.id() == ID_array && e.operands().empty(); }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I love these iterators and lambda expressions!
Ok, so these are part of the input? I wasn't aware of that.
If the code being touched here is the only layer between user input and the SAT solver then the changes as they are are good. If there is a further layer that does the conversion towards the SAT solver, then that code should be returning an ERROR (rather than a segmentation fault). |
It's a problem I encountered while working on TG-592 but not directly related.
Actually I cannot find an example at the moment. I will make it into a precondition instead so that when it happens again, we have a better error message than just segmentation fault. |
#include <assert.h>
#include <stdlib.h>
struct clause {
int size;
int variables[0];
};
int main (int argc, char **argv) {
struct clause *p = malloc(sizeof(struct clause) + 3 * sizeof(int));
p->size = 3;
p->variables[0] = 1;
p->variables[1] = 2;
p->variables[2] = 3;
struct clause *q = malloc(sizeof(struct clause) + 3 * sizeof(int));
*q = *p;
assert(q->variables[0] == 1);
assert(q->variables[1] == 2);
assert(q->variables[2] == 3);
free(p);
free(q);
return 0;
} A legitimate example of a zero-sized array. Seems to work FWIW. |
I like the idea of a PRECONDITION but I'm not quite sure where it should go. Presumably the same thing happens when the solver is used without --refine-strings ? Do you know where it crashes? |
@martin-cs the following code is a unit test that cause the error (Process finished with exit code 134 (interrupted by signal 6: SIGABRT)) #include <testing-utils/catch.hpp>
#include <solvers/refinement/bv_refinement.h>
#include <solvers/sat/satcheck.h>
#include <util/symbol_table.h>
#include <java_bytecode/java_types.h>
#include <util/arith_tools.h>
#include <iostream>
SCENARIO("empty array in bv_refinement",
"[core][solvers][refinement][bv_refinement]")
{
symbol_tablet symtbl;
const namespacet ns(symtbl);
satcheck_no_simplifiert sat_check;
bv_refinementt::infot info;
info.ns=&ns;
info.prop=&sat_check;
info.refine_arithmetic=true;
info.refine_arrays=true;
info.max_node_refinement=5;
bv_refinementt solver(info);
const typet int_type = java_int_type();
const symbol_exprt i("i", int_type);
const array_exprt arr(array_typet(int_type, from_integer(0, int_type)));
WHEN("axiom contains empty array")
{
const implies_exprt axiom(
and_exprt(
binary_relation_exprt(i, ID_lt, from_integer(0, int_type)),
binary_relation_exprt(i, ID_ge, from_integer(0, int_type))),
equal_exprt(index_exprt(arr, i), from_integer(12, int_type)));
solver << axiom;
if(solver() == decision_proceduret::resultt::D_SATISFIABLE)
std::cout << "i = " << numeric_cast_v<std::size_t>(solver.get(i)) << std::endl;
else
std::cout << "unsatisfiable";
}
} |
Given that @martin-cs' example works, while the lower-level version compiled by @romainbrenguier doesn't I am starting to wonder whether the problem just resides in the refinement code? From the example I'd certainly say that there is a problem in a middle layer, which ought to be coming up with a correct answer.
|
closing this PR as #1668 should fix the root cause of the bug |
Passing empty arrays causes segmentation fault.