Avoid triggering a division by zero in the overflow check
[smatch.git] / check_resource_size.c
blob6e8aa63ee3c3822ec2c1926a504805d4b49921b9
1 /*
2 * smatch/check_resource_size.c
4 * Copyright (C) 2010 Dan Carpenter.
6 * Licensed under the Open Software License version 1.1
8 */
10 #include "smatch.h"
12 static int my_id;
13 extern int check_assigned_expr_id;
15 static int is_probably_ok(struct expression *expr)
17 expr = strip_expr(expr);
19 if (expr->type == EXPR_BINOP)
20 return 1;
21 if (expr->type == EXPR_SIZEOF)
22 return 1;
24 return 0;
27 static void verify_size_expr(struct expression *expr)
29 if (expr->type != EXPR_BINOP)
30 return;
31 if (expr->op != '-')
32 return;
33 if (is_probably_ok(expr->left))
34 return;
35 if (is_probably_ok(expr->right))
36 return;
37 sm_msg("warn: consider using resource_size() here");
40 static void handle_assigned_expr(struct expression *expr)
42 struct smatch_state *state;
44 state = get_state_expr(check_assigned_expr_id, expr);
45 if (!state || !state->data)
46 return;
47 expr = (struct expression *)state->data;
48 verify_size_expr(expr);
51 static void match_resource(const char *fn, struct expression *expr, void *_arg_no)
53 struct expression *arg_expr;
54 int arg_no = PTR_INT(_arg_no);
56 arg_expr = get_argument_from_call_expr(expr->args, arg_no);
57 arg_expr = strip_expr(arg_expr);
58 if (!arg_expr)
59 return;
61 if (arg_expr->type == EXPR_SYMBOL) {
62 handle_assigned_expr(arg_expr);
63 return;
65 verify_size_expr(arg_expr);
68 void check_resource_size(int id)
70 my_id = id;
72 if (option_project != PROJ_KERNEL)
73 return;
75 add_function_hook("ioremap_nocache", &match_resource, (void *)1);
76 add_function_hook("ioremap", &match_resource, (void *)1);
77 add_function_hook("__request_region", &match_resource, (void *)2);
78 add_function_hook("__release_region", &match_resource, (void *)2);
79 add_function_hook("__devm_request_region", &match_resource, (void *)3);
80 add_function_hook("__devm_release_region", &match_resource, (void *)3);