Skip to content

Commit

Permalink
preparation for new flow analysis
Browse files Browse the repository at this point in the history
  • Loading branch information
thradams committed Mar 24, 2024
1 parent 2561775 commit 1a86f7b
Show file tree
Hide file tree
Showing 4 changed files with 387 additions and 21 deletions.
22 changes: 10 additions & 12 deletions src/file.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
void* _Owner malloc(unsigned long size);
void* _Owner calloc(unsigned long n , unsigned long size);
void free(void* _Owner ptr);

struct Y {
Expand All @@ -14,18 +14,16 @@ struct X {
struct Y *pY;
};

void init(struct X * p);

int main() {
struct X x = {0};
static_debug(x);
init(&x);
struct X * _Owner x = calloc(1,sizeof * x);
static_debug(x);
static_state(x.p1, "maybe-null");
static_state(x.i, "any");
static_state(x.pY, "maybe-null");
static_state(x.pY->p0, "maybe-null");
static_state(x.pY->p2, "maybe-null");
static_state(x.pY->i2, "any");
static_state(x, "maybe-null");

static_state(x->p1, "null");
static_state(x->i, "zero");
static_state(x->pY, "null");
static_state(x->pY->p0, "uninitialized");
static_state(x->pY->p2, "uninitialized");
static_state(x->pY->i2, "uninitialized");
free(x);
}
190 changes: 186 additions & 4 deletions src/flow_visit.c
Original file line number Diff line number Diff line change
Expand Up @@ -628,7 +628,7 @@ static void pop_states(struct flow_visit_ctx* ctx, int n)
static void flow_visit_initializer(struct flow_visit_ctx* ctx, struct initializer* p_initializer);
static void flow_visit_declarator(struct flow_visit_ctx* ctx, struct declarator* p_declarator);

static void flow_visit_init_declarator(struct flow_visit_ctx* ctx, struct init_declarator* p_init_declarator)
static void flow_visit_init_declarator_current(struct flow_visit_ctx* ctx, struct init_declarator* p_init_declarator)
{
if (p_init_declarator->p_declarator)
{
Expand Down Expand Up @@ -797,6 +797,188 @@ static void flow_visit_init_declarator(struct flow_visit_ctx* ctx, struct init_d
// flow_visit_declarator(ctx, p_init_declarator->p_declarator);
}

static void flow_visit_init_declarator_new(struct flow_visit_ctx* ctx, struct init_declarator* p_init_declarator)
{
if (p_init_declarator->p_declarator)
{
flow_visit_declarator(ctx, p_init_declarator->p_declarator);
}

if (p_init_declarator->initializer)
{
if (p_init_declarator->initializer->assignment_expression)
{
flow_visit_expression(ctx, p_init_declarator->initializer->assignment_expression);
}
else
{
assert(p_init_declarator->initializer->braced_initializer != NULL);
if (p_init_declarator->initializer->braced_initializer)
{
flow_visit_bracket_initializer_list(ctx,
p_init_declarator->initializer->braced_initializer);
}
}
}

if (p_init_declarator->p_declarator->type.category != TYPE_CATEGORY_FUNCTION)
{
if (p_init_declarator->initializer &&
p_init_declarator->initializer->assignment_expression)
{

struct object temp_obj = { 0 };
struct object* p_right_object =
expression_get_object(p_init_declarator->initializer->assignment_expression, &temp_obj);

bool bool_source_zero_value = constant_value_is_valid(&p_init_declarator->initializer->assignment_expression->constant_value) &&
constant_value_to_ull(&p_init_declarator->initializer->assignment_expression->constant_value) == 0;


//cast?
if (p_init_declarator->initializer->assignment_expression->expression_type == POSTFIX_FUNCTION_CALL &&
p_init_declarator->initializer->assignment_expression->left &&
p_init_declarator->initializer->assignment_expression->left->declarator &&
p_init_declarator->initializer->assignment_expression->left->declarator->name)
{
if (strcmp(p_init_declarator->initializer->assignment_expression->left->declarator->name->lexeme, "calloc") == 0)
{
if (object_get_pointed_object(&p_init_declarator->p_declarator->object))
{
struct type t = type_remove_pointer(&p_init_declarator->p_declarator->type);
object_set_zero(&t, object_get_pointed_object(&p_init_declarator->p_declarator->object));
type_destroy(&t);
}

p_init_declarator->p_declarator->object.state = OBJECT_STATE_NOT_NULL | OBJECT_STATE_NULL;

}
else if (strcmp(p_init_declarator->initializer->assignment_expression->left->declarator->name->lexeme, "malloc") == 0)
{
if (object_get_pointed_object(&p_init_declarator->p_declarator->object))
{
struct type t = type_remove_pointer(&p_init_declarator->p_declarator->type);
object_set_uninitialized(&t, object_get_pointed_object(&p_init_declarator->p_declarator->object));
type_destroy(&t);
}




p_init_declarator->p_declarator->object.state = OBJECT_STATE_NOT_NULL | OBJECT_STATE_NULL;
}
else
{
const struct token* const token_position =
p_init_declarator->p_declarator->name ?
p_init_declarator->p_declarator->name :
p_init_declarator->p_declarator->first_token
;

object_assignment(ctx->ctx, p_right_object,
&p_init_declarator->initializer->assignment_expression->type,
&p_init_declarator->p_declarator->object,
&p_init_declarator->p_declarator->type,
token_position,
bool_source_zero_value,
OBJECT_STATE_MOVED,
ASSIGMENT_TYPE_OBJECTS);
}
}
else
{
const struct token* const token_position =
p_init_declarator->p_declarator->name ?
p_init_declarator->p_declarator->name :
p_init_declarator->p_declarator->first_token
;

object_assignment(ctx->ctx,
p_right_object,
&p_init_declarator->initializer->assignment_expression->type,
&p_init_declarator->p_declarator->object,
&p_init_declarator->p_declarator->type,
token_position,
bool_source_zero_value,
OBJECT_STATE_MOVED,
ASSIGMENT_TYPE_OBJECTS);
}

object_destroy(&temp_obj);
}
else if (p_init_declarator->initializer &&
p_init_declarator->initializer->braced_initializer)
{
bool is_zero_initialized = false;
if (p_init_declarator->initializer->braced_initializer->initializer_list == NULL)
{
is_zero_initialized = true;
}
else
{
if (p_init_declarator->initializer->braced_initializer->initializer_list->size == 1 &&
p_init_declarator->initializer->braced_initializer->initializer_list->head->assignment_expression)
{
struct constant_value* p_constant_value =
&p_init_declarator->initializer->braced_initializer->initializer_list->head->assignment_expression->constant_value;

if (constant_value_is_valid(p_constant_value) &&
constant_value_to_ull(p_constant_value) == 0)
{
is_zero_initialized = true;
}

}
}

if (is_zero_initialized)
{
object_set_zero(&p_init_declarator->p_declarator->type, &p_init_declarator->p_declarator->object);
}
else
{
object_set_zero(&p_init_declarator->p_declarator->type, &p_init_declarator->p_declarator->object);
}
}
else
{
if (p_init_declarator->p_declarator->declaration_specifiers &&
(
(p_init_declarator->p_declarator->declaration_specifiers->storage_class_specifier_flags & STORAGE_SPECIFIER_EXTERN) ||
(p_init_declarator->p_declarator->declaration_specifiers->storage_class_specifier_flags & STORAGE_SPECIFIER_STATIC)
)
)
{
object_set_zero(&p_init_declarator->p_declarator->type, &p_init_declarator->p_declarator->object);
}
else
{
object_set_uninitialized(&p_init_declarator->p_declarator->type, &p_init_declarator->p_declarator->object);
}



}
}


//if (p_init_declarator->initializer)
// flow_visit_initializer(ctx, p_init_declarator->initializer);

//if (p_init_declarator->p_declarator)
// flow_visit_declarator(ctx, p_init_declarator->p_declarator);
}


static void flow_visit_init_declarator(struct flow_visit_ctx* ctx, struct init_declarator* p_init_declarator)
{
#if NEW_FLOW_ANALYSIS
flow_visit_init_declarator_new(ctx, p_init_declarator);
#else
flow_visit_init_declarator_current(ctx, p_init_declarator);
#endif
}

static void flow_visit_init_declarator_list(struct flow_visit_ctx* ctx, struct init_declarator_list* p_init_declarator_list);

static void flow_visit_declaration_specifiers(struct flow_visit_ctx* ctx,
Expand Down Expand Up @@ -2166,7 +2348,7 @@ static void flow_visit_jump_statement(struct flow_visit_ctx* ctx, struct jump_st
{
struct object temp_obj = { 0 };
struct object* p_object = expression_get_object(p_jump_statement->expression_opt, &temp_obj);


checked_read_object(ctx->ctx,
&p_jump_statement->expression_opt->type,
Expand Down Expand Up @@ -2203,7 +2385,7 @@ static void flow_visit_jump_statement(struct flow_visit_ctx* ctx, struct jump_st
&dest_object, /*dest object*/
&p_jump_statement->expression_opt->type, /*source type*/
p_object /*source*/
);
);
#endif
object_destroy(&dest_object);
object_destroy(&temp_obj);
Expand Down Expand Up @@ -2474,7 +2656,7 @@ static void flow_visit_static_assert_declaration(struct flow_visit_ctx* ctx, str
if (strcmp(lexeme, "\"zero\"") == 0)
{
//gives the semantics of {0} or calloc
set_direct_state(&p_static_assert_declaration->constant_expression->type, p_obj, OBJECT_STATE_ZERO);
object_set_zero(&p_static_assert_declaration->constant_expression->type, p_obj);
}
else
{
Expand Down
Loading

0 comments on commit 1a86f7b

Please sign in to comment.