*new* check_macros: find macro precedence bugs
[smatch.git] / check_le16.c
blobcdd3827ac51ae6ec37dcac550d02171feedfbc28
1 /*
2 * smatch/check_le16.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;
14 static int is_le16(struct symbol *type)
16 if (type->ctype.alignment != 2)
17 return 0;
18 if (!(type->ctype.modifiers & MOD_UNSIGNED))
19 return 0;
20 return 1;
23 static void match_no_le16_param(const char *fn, struct expression *expr, void *param)
25 struct expression *arg;
26 struct symbol *type;
27 char *name;
29 arg = get_argument_from_call_expr(expr->args, (int)param);
30 arg = strip_parens(arg);
31 if (!arg)
32 return;
33 if (arg->type != EXPR_FORCE_CAST)
34 return;
36 type = get_type(arg);
37 if (!is_le16(type))
38 return;
40 arg = strip_expr(arg);
41 name = get_variable_from_expr_complex(arg, NULL);
42 sm_msg("warn: don't need to call cpu_to_le16() for '%s'", name);
43 free_string(name);
46 static void register_funcs_from_file(void)
48 struct token *token;
49 const char *func;
50 int arg;
52 token = get_tokens_file("kernel.no_le16");
53 if (!token)
54 return;
55 if (token_type(token) != TOKEN_STREAMBEGIN)
56 return;
57 token = token->next;
58 while (token_type(token) != TOKEN_STREAMEND) {
59 if (token_type(token) != TOKEN_IDENT)
60 return;
61 func = show_ident(token->ident);
62 token = token->next;
63 if (token_type(token) != TOKEN_NUMBER)
64 return;
65 arg = atoi(token->number);
66 add_function_hook(func, &match_no_le16_param, INT_PTR(arg));
67 token = token->next;
69 clear_token_alloc();
72 void check_le16(int id)
74 if (option_project != PROJ_KERNEL)
75 return;
76 if (!option_spammy)
77 return;
78 my_id = id;
79 register_funcs_from_file();