Print this page
11972 resync smatch

*** 225,241 **** if (offset < 0) return 0; return 1; } ! static int is_ignored_macro(void) { struct expression *expr; char *name; expr = get_faked_expression(); if (!expr || expr->type != EXPR_ASSIGNMENT) return 0; name = get_macro_name(expr->right->pos); if (!name) return 0; if (strcmp(name, "container_of") == 0) --- 225,274 ---- if (offset < 0) return 0; return 1; } ! static bool is_driver_data(void) { + static struct expression *prev_expr; struct expression *expr; char *name; + static bool prev_ret; + bool ret = false; expr = get_faked_expression(); if (!expr || expr->type != EXPR_ASSIGNMENT) + return false; + + if (expr == prev_expr) + return prev_ret; + prev_expr = expr; + + name = expr_to_str(expr->right); + if (!name) { + prev_ret = false; + return false; + } + + if (strstr(name, "get_drvdata(") || + strstr(name, "dev.driver_data") || + strstr(name, "dev->driver_data")) + ret = true; + + free_string(name); + + prev_ret = ret; + return ret; + } + + static int is_ignored_macro(void) + { + struct expression *expr; + char *name; + + expr = get_faked_expression(); + if (!expr || expr->type != EXPR_ASSIGNMENT || expr->op != '=') return 0; name = get_macro_name(expr->right->pos); if (!name) return 0; if (strcmp(name, "container_of") == 0)
*** 246,255 **** --- 279,302 ---- return 1; if (strcmp(name, "list_first_entry") == 0) return 1; if (strcmp(name, "hlist_entry") == 0) return 1; + if (strcmp(name, "per_cpu_ptr") == 0) + return 1; + if (strcmp(name, "raw_cpu_ptr") == 0) + return 1; + if (strcmp(name, "this_cpu_ptr") == 0) + return 1; + + if (strcmp(name, "TRACE_EVENT") == 0) + return 1; + if (strcmp(name, "DECLARE_EVENT_CLASS") == 0) + return 1; + if (strcmp(name, "DEFINE_EVENT") == 0) + return 1; + if (strstr(name, "for_each")) return 1; return 0; }
*** 264,277 **** --- 311,344 ---- if (!expr || expr->type != EXPR_CALL || expr->fn->type != EXPR_SYMBOL) return 0; if (sym_name_is("kmalloc", expr->fn)) return 1; + if (sym_name_is("vmalloc", expr->fn)) + return 1; + if (sym_name_is("kvmalloc", expr->fn)) + return 1; + if (sym_name_is("kmalloc_array", expr->fn)) + return 1; + if (sym_name_is("vmalloc_array", expr->fn)) + return 1; + if (sym_name_is("kvmalloc_array", expr->fn)) + return 1; + + if (sym_name_is("mmu_memory_cache_alloc", expr->fn)) + return 1; + if (sym_name_is("kmem_alloc", expr->fn)) + return 1; + if (sym_name_is("alloc_pages", expr->fn)) + return 1; + if (sym_name_is("netdev_priv", expr->fn)) return 1; if (sym_name_is("dev_get_drvdata", expr->fn)) return 1; + if (sym_name_is("i2c_get_clientdata", expr->fn)) + return 1; return 0; } static int is_uncasted_pointer_assign(void)
*** 292,301 **** --- 359,371 ---- right_type = get_type(expr->right); if (!left_type || !right_type) return 0; + if (left_type->type == SYM_STRUCT && left_type == right_type) + return 1; + if (left_type->type != SYM_PTR && left_type->type != SYM_ARRAY) return 0; if (right_type->type != SYM_PTR && right_type->type != SYM_ARRAY)
*** 394,403 **** --- 464,475 ---- if (!cur_func_sym) return; type = get_type(expr->left); + if (type && type->type == SYM_STRUCT) + return; member = get_member_name(expr->left); if (!member) return; /* if we're saying foo->mtu = bar->mtu then that doesn't add information */
*** 414,423 **** --- 486,497 ---- goto free; if (is_uncasted_fn_param_from_db()) goto free; if (is_container_of()) goto free; + if (is_driver_data()) + goto free; add_fake_type_val(member, alloc_whole_rl(get_type(expr->left)), is_ignored_fake_assignment()); goto free; } if (expr->op == '=') {
*** 499,526 **** static void asm_expr(struct statement *stmt) { struct expression *expr; struct range_list *rl; char *member; - int state = 0; FOR_EACH_PTR(stmt->asm_outputs, expr) { ! switch (state) { ! case 0: /* identifier */ ! case 1: /* constraint */ ! state++; ! continue; ! case 2: /* expression */ ! state = 0; ! member = get_member_name(expr); if (!member) continue; ! rl = alloc_whole_rl(get_type(expr)); add_type_val(member, rl); free_string(member); - continue; - } } END_FOR_EACH_PTR(expr); } static void db_param_add(struct expression *expr, int param, char *key, char *value) { --- 573,590 ---- static void asm_expr(struct statement *stmt) { struct expression *expr; struct range_list *rl; char *member; FOR_EACH_PTR(stmt->asm_outputs, expr) { ! member = get_member_name(expr->expr); if (!member) continue; ! rl = alloc_whole_rl(get_type(expr->expr)); add_type_val(member, rl); free_string(member); } END_FOR_EACH_PTR(expr); } static void db_param_add(struct expression *expr, int param, char *key, char *value) {
*** 540,549 **** --- 604,626 ---- arg = get_argument_from_call_expr(expr->args, param); arg = strip_expr(arg); if (!arg) return; type = get_member_type_from_key(arg, key); + /* + * The situation here is that say we memset() a void pointer to zero + * then that's returned to the called as "*$ = 0;" but on the caller's + * side it's not void, it's a struct. + * + * So the question is should we be passing that slightly bogus + * information back to the caller? Maybe, maybe not, but either way we + * are not going to record it here because a struct can't be zero. + * + */ + if (type && type->type == SYM_STRUCT) + return; + if (arg->type != EXPR_PREOP || arg->op != '&') return; arg = strip_expr(arg->unop); member = get_member_name(arg);