#include "smatch.h"
#include "smatch_slist.h"
static int my_id;
STATE(true_path);
STATE(false_path);
void record_condition(struct expression *expr)
{
char name[32];
sval_t val;
if (get_value(expr, &val))
return;
if (__in_pre_condition)
return;
snprintf(name, sizeof(name), "condition %p", expr);
set_true_false_states(my_id, name, NULL, &true_path, &false_path);
}
void register_parsed_conditions(int id)
{
my_id = id;
add_hook(&record_condition, CONDITION_HOOK);
}
static void filter_by_sm(struct sm_state *sm,
struct state_list **true_stack,
struct state_list **false_stack)
{
if (!sm)
return;
if (sm->state == &true_path)
add_ptr_list(true_stack, sm);
else if (sm->state == &false_path)
add_ptr_list(false_stack, sm);
if (sm->merged) {
filter_by_sm(sm->left, true_stack, false_stack);
filter_by_sm(sm->right, true_stack, false_stack);
}
}
struct sm_state *parsed_condition_implication_hook(struct expression *expr,
struct state_list **true_stack,
struct state_list **false_stack)
{
struct state_list *tmp_true = NULL;
struct state_list *tmp_false = NULL;
struct sm_state *sm, *tmp;
char name[32];
snprintf(name, sizeof(name), "condition %p", expr);
sm = get_sm_state(my_id, name, NULL);
if (!sm)
return NULL;
if (!sm->merged)
return NULL;
filter_by_sm(sm, &tmp_true, &tmp_false);
if (!tmp_true && !tmp_false)
return NULL;
FOR_EACH_PTR(tmp_true, tmp) {
add_ptr_list(true_stack, tmp);
} END_FOR_EACH_PTR(tmp);
FOR_EACH_PTR(tmp_false, tmp) {
add_ptr_list(false_stack, tmp);
} END_FOR_EACH_PTR(tmp);
free_slist(&tmp_true);
free_slist(&tmp_false);
return sm;
}