ranges: don't allow inverted ranges
[smatch.git] / smatch_param_set.c
blob7bbc8d5c41345ee9e37a71e89d97558d7d2cef2e
1 /*
2 * sparse/smatch_param_set.c
4 * Copyright (C) 2012 Oracle.
6 * Licensed under the Open Software License version 1.1
8 */
10 #include "scope.h"
11 #include "smatch.h"
12 #include "smatch_slist.h"
13 #include "smatch_extra.h"
15 static int my_id;
17 static struct smatch_state *unmatched_state(struct sm_state *sm)
19 return alloc_estate_empty();
22 static void extra_mod_hook(const char *name, struct symbol *sym, struct smatch_state *state)
24 set_state(my_id, name, sym, state);
27 static const char *get_param_name(struct sm_state *sm)
29 char *param_name;
30 int name_len;
31 static char buf[256];
33 param_name = sm->sym->ident->name;
34 name_len = strlen(param_name);
36 if (sm->name[name_len] == '-' && /* check for '-' from "->" */
37 strncmp(sm->name, param_name, name_len) == 0) {
38 snprintf(buf, sizeof(buf), "$$%s", sm->name + name_len);
39 return buf;
40 } else if (sm->name[0] == '*' && strcmp(sm->name + 1, param_name) == 0) {
41 return "*$$";
43 return NULL;
46 static void print_one_return_value_param(int return_id, char *return_ranges,
47 int param, struct sm_state *sm, char *implied_rl,
48 struct state_list *slist)
50 const char *param_name;
52 param_name = get_param_name(sm);
53 if (!param_name)
54 return;
56 sm_msg("info: return_param_add %d %d '%s' '%s' '%s' %s",
57 return_id, param, return_ranges,
58 param_name, implied_rl, global_static());
61 static void print_return_value_param(int return_id, char *return_ranges, struct expression *expr, struct state_list *slist)
63 struct state_list *my_slist;
64 struct sm_state *sm;
65 struct smatch_state *extra;
66 int param;
67 struct range_list *rl;
69 my_slist = get_all_states_slist(my_id, slist);
71 FOR_EACH_PTR(my_slist, sm) {
72 if (!estate_rl(sm->state))
73 continue;
74 extra = get_state_slist(slist, SMATCH_EXTRA, sm->name, sm->sym);
75 if (!estate_rl(extra))
76 continue;
77 rl = rl_intersection(estate_rl(sm->state), estate_rl(extra));
78 if (!rl)
79 continue;
81 param = get_param_num_from_sym(sm->sym);
82 if (param < 0)
83 continue;
84 if (!sm->sym->ident)
85 continue;
86 print_one_return_value_param(return_id, return_ranges, param, sm, show_rl(rl), slist);
87 } END_FOR_EACH_PTR(sm);
90 void register_param_set(int id)
92 if (!option_info)
93 return;
95 my_id = id;
97 add_extra_mod_hook(&extra_mod_hook);
98 add_unmatched_state_hook(my_id, &unmatched_state);
99 add_merge_hook(my_id, &merge_estates);
100 add_returned_state_callback(&print_return_value_param);