From 4302101de40c19742faed379be73bd67a89b430b Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 14 Feb 2013 15:13:32 +0300 Subject: [PATCH] *new* check_struct_type: if we allocate an unexpected type of struct Complain about code like this: struct foo *p; p = kmalloc(sizeof(struct bar), GFP_KERNEL); These are mostly real bugs, but they are allocating more memory than we need not less. Signed-off-by: Dan Carpenter --- check_list.h | 1 + check_struct_type.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) create mode 100644 check_struct_type.c diff --git a/check_list.h b/check_list.h index d2f61257..a4de1cfb 100644 --- a/check_list.h +++ b/check_list.h @@ -83,6 +83,7 @@ CK(check_or_vs_and) CK(check_passes_sizeof) CK(check_assign_vs_compare) CK(check_missing_break) +CK(check_struct_type) /* <- your test goes here */ /* CK(register_template) */ diff --git a/check_struct_type.c b/check_struct_type.c new file mode 100644 index 00000000..0982e729 --- /dev/null +++ b/check_struct_type.c @@ -0,0 +1,56 @@ +/* + * sparse/check_struct_type.c + * + * Copyright (C) 2013 Oracle. + * + * Licensed under the Open Software License version 1.1 + * + */ + +#include "smatch.h" + +static int my_id; + +static void match_assign(const char *fn, struct expression *expr, void *_size_arg) +{ + int size_arg = PTR_INT(_size_arg); + struct expression *left; + struct expression *call; + struct expression *arg; + struct symbol *left_type; + struct symbol *size_type; + + left = strip_expr(expr->left); + left_type = get_type(left); + if (!left_type || left_type->type != SYM_PTR) + return; + left_type = get_real_base_type(left_type); + if (!left_type || left_type->type != SYM_STRUCT) + return; + + call = strip_expr(expr->right); + arg = get_argument_from_call_expr(call->args, size_arg); + if (!arg || arg->type != EXPR_SIZEOF || !arg->cast_type) + return; + size_type = arg->cast_type; + if (size_type->type != SYM_NODE) + return; + size_type = get_real_base_type(size_type); + if (size_type->type != SYM_STRUCT) + return; + if (strcmp(left_type->ident->name, size_type->ident->name) == 0) + return; + sm_msg("warn: struct type mismatch '%s vs %s'", left_type->ident->name, + size_type->ident->name); + +} + +void check_struct_type(int id) +{ + my_id = id; + + if (option_project == PROJ_KERNEL) { + add_function_assign_hook("kmalloc", &match_assign, INT_PTR(0)); + add_function_assign_hook("kzalloc", &match_assign, INT_PTR(0)); + } +} -- 2.11.4.GIT