From 595514a1ba6087f9d46b4bb0e5d868b40db9a82f Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 20 Apr 2018 15:59:06 +0300 Subject: [PATCH] flow/expressions/function_hooks: re-fix is_assigned_call() The is_assigned_call() is totally essential so that we don't parse function calls twice as an assignment and then as a normal function call. It's pretty complicated because we do a bunch of fake assignments. For initializers, for things like "foo = bar() ?: 0;" or "foo = (({blah; blah; bar();}));". It's not always clear what the ->parent struct should be I think... Anyway, this change sort of reverts it to how it used to be. In assign_expression() we allocate a normal expression struct so it isn't freed at the end of the function and we set the ->parent to then assignment. There is still an issue where I guess we parse the call first, then fake an assignment, and then parse that. It's the reverse order from normal so we end up parsing the function twice and it causes one or two puzzling false positives in the kernel. I need to think about that. Signed-off-by: Dan Carpenter --- smatch_conditions.c | 40 +++++++++++++--------------------------- smatch_expressions.c | 3 ++- smatch_flow.c | 9 --------- 3 files changed, 15 insertions(+), 37 deletions(-) diff --git a/smatch_conditions.c b/smatch_conditions.c index f5ffe898..0d34434a 100644 --- a/smatch_conditions.c +++ b/smatch_conditions.c @@ -642,26 +642,22 @@ int __handle_select_assigns(struct expression *expr) __split_whole_condition(right->conditional); if (!is_false) { - struct expression fake_expr = { - .smatch_flags = Fake, - }; + struct expression *fake_expr; if (right->cond_true) - set_fake_assign(&fake_expr, expr->left, expr->op, right->cond_true); + fake_expr = assign_expression(expr->left, expr->op, right->cond_true); else - set_fake_assign(&fake_expr, expr->left, expr->op, right->conditional); - __split_expr(&fake_expr); + fake_expr = assign_expression(expr->left, expr->op, right->conditional); + __split_expr(fake_expr); final_states = clone_stree(__get_cur_stree()); } __use_false_states(); if (!is_true) { - struct expression fake_expr = { - .smatch_flags = Fake, - }; + struct expression *fake_expr; - set_fake_assign(&fake_expr, expr->left, expr->op, right->cond_false); - __split_expr(&fake_expr); + fake_expr = assign_expression(expr->left, expr->op, right->cond_false); + __split_expr(fake_expr); merge_stree(&final_states, __get_cur_stree()); } @@ -716,7 +712,7 @@ int __handle_expr_statement_assigns(struct expression *expr) stmt = right->statement; if (stmt->type == STMT_COMPOUND) { struct statement *last_stmt; - struct expression fake_assign = { .smatch_flags = Fake, }; + struct expression *fake_assign; struct expression fake_expr_stmt = { .smatch_flags = Fake, }; last_stmt = split_then_return_last(stmt); @@ -730,26 +726,16 @@ int __handle_expr_statement_assigns(struct expression *expr) fake_expr_stmt.op = 0; fake_expr_stmt.statement = last_stmt; - fake_assign.pos = last_stmt->pos; - fake_assign.op = expr->op; - fake_assign.type = EXPR_ASSIGNMENT; - fake_assign.left = expr->left; - fake_assign.right = &fake_expr_stmt; - - __split_expr(&fake_assign); + fake_assign = assign_expression(expr->left, expr->op, &fake_expr_stmt); + __split_expr(fake_assign); __pass_to_client(stmt, STMT_HOOK_AFTER); __call_scope_hooks(); } else if (stmt->type == STMT_EXPRESSION) { - struct expression fake_assign = { .smatch_flags = Fake, }; - - fake_assign.pos = stmt->pos; - fake_assign.op = expr->op; - fake_assign.type = EXPR_ASSIGNMENT; - fake_assign.left = expr->left; - fake_assign.right = stmt->expression; + struct expression *fake_assign; - __split_expr(&fake_assign); + fake_assign = assign_expression(expr->left, expr->op, stmt->expression); + __split_expr(fake_assign); } else { __split_stmt(stmt); diff --git a/smatch_expressions.c b/smatch_expressions.c index 201f9910..aafc213c 100644 --- a/smatch_expressions.c +++ b/smatch_expressions.c @@ -86,7 +86,8 @@ struct expression *assign_expression(struct expression *left, int op, struct exp { struct expression *expr; - expr = alloc_tmp_expression(right->pos, EXPR_ASSIGNMENT); + /* FIXME: make this a tmp expression. */ + expr = alloc_expression(right->pos, EXPR_ASSIGNMENT); expr->op = op; expr->left = left; expr->right = right; diff --git a/smatch_flow.c b/smatch_flow.c index 3f72d160..4c8c81a9 100644 --- a/smatch_flow.c +++ b/smatch_flow.c @@ -154,15 +154,6 @@ int is_assigned_call(struct expression *expr) strip_expr(parent->right) == expr) return 1; - /* - * The problem is that the fake assignments we do in the initializer - * don't have a real assignment backing them so we don't set the - * ->parent pointer. This is a bit of an ugly hack, probably. - * - */ - if (!parent && __cur_stmt && __cur_stmt->type == STMT_DECLARATION) - return 1; - return 0; } -- 2.11.4.GIT