math: revert accidentally committed code
[smatch.git] / smatch_strlen.c
blob8a68c838f3c709e85fd5ecdc97689cf37f4993d5
1 /*
2 * smatch/smatch_strlen.c
4 * Copyright (C) 2013 Oracle.
6 * Licensed under the Open Software License version 1.1
8 */
10 #include <stdlib.h>
11 #include <errno.h>
12 #include "parse.h"
13 #include "smatch.h"
14 #include "smatch_slist.h"
15 #include "smatch_extra.h"
17 static int my_strlen_id;
19 static void set_strlen_undefined(struct sm_state *sm, struct expression *mod_expr)
21 set_state(sm->owner, sm->name, sm->sym, &undefined);
24 static void match_strlen(const char *fn, struct expression *expr, void *unused)
26 struct expression *right;
27 struct expression *str;
28 struct expression *len_expr;
29 char *len_name;
30 struct smatch_state *state;
32 right = strip_expr(expr->right);
33 str = get_argument_from_call_expr(right->args, 0);
34 len_expr = strip_expr(expr->left);
36 len_name = expr_to_var(len_expr);
37 if (!len_name)
38 return;
40 state = __alloc_smatch_state(0);
41 state->name = len_name;
42 state->data = len_expr;
44 set_state_expr(my_strlen_id, str, state);
47 int get_size_from_strlen(struct expression *expr)
49 struct smatch_state *state;
50 sval_t len;
52 state = get_state_expr(my_strlen_id, expr);
53 if (!state || !state->data)
54 return 0;
55 if (!get_implied_max((struct expression *)state->data, &len))
56 return 0;
57 if (sval_is_max(len))
58 return 0;
59 if (len.uvalue > INT_MAX - 1 || len.value < 0)
60 return 0;
61 return len.value + 1; /* add one because strlen doesn't include the NULL */
64 void register_strlen(int id)
66 my_strlen_id = id;
67 add_function_assign_hook("strlen", &match_strlen, NULL);
68 add_modification_hook(my_strlen_id, &set_strlen_undefined);