2 * smatch/check_pointer_math.c
4 * Copyright (C) 2012 Oracle.
6 * Licensed under the Open Software License version 1.1
16 static void set_undefined(struct sm_state
*sm
, struct expression
*mod_expr
)
18 if (sm
->state
== &size_in_bytes
)
19 set_state(my_id
, sm
->name
, sm
->sym
, &undefined
);
22 static int is_sizeof(struct expression
*expr
)
24 return (expr
->type
== EXPR_SIZEOF
);
27 static int is_align(struct expression
*expr
)
30 struct expression
*outside_expr
;
32 /* check that we aren't inside the ALIGN() macro itself */
33 outside_expr
= last_ptr_list((struct ptr_list
*)big_expression_stack
);
34 if (outside_expr
&& positions_eq(expr
->pos
, outside_expr
->pos
))
37 name
= get_macro_name(expr
->pos
);
38 if (name
&& strcmp(name
, "ALIGN") == 0)
43 static int is_size_in_bytes(struct expression
*expr
)
51 if (get_state_expr(my_id
, expr
) == &size_in_bytes
)
57 static void match_binop(struct expression
*expr
)
64 type
= get_pointer_type(expr
->left
);
67 if (type
->bit_size
<= 8) /* ignore void, bool and char pointers*/
69 if (!is_size_in_bytes(expr
->right
))
72 name
= expr_to_str(expr
->left
);
73 sm_msg("warn: potential pointer math issue ('%s' is a %d bit pointer)",
74 name
, type
->bit_size
);
78 static void match_assign(struct expression
*expr
)
83 if (!is_size_in_bytes(expr
->right
))
85 set_state_expr(my_id
, expr
->left
, &size_in_bytes
);
88 static void check_assign(struct expression
*expr
)
93 type
= get_pointer_type(expr
->left
);
96 if (type_bits(type
) == 8 || type_bits(type
) == -1)
98 if (!is_size_in_bytes(expr
->right
))
100 name
= expr_to_var(expr
->left
);
101 sm_msg("warn: potential pointer math issue ('%s' is a %d bit pointer)",
102 name
, type_bits(type
));
106 void check_pointer_math(int id
)
109 add_hook(&match_binop
, BINOP_HOOK
);
110 add_hook(&match_assign
, ASSIGNMENT_HOOK
);
111 add_hook(&check_assign
, ASSIGNMENT_HOOK
);
112 add_modification_hook(my_id
, &set_undefined
);