scope: fix is_outer_stmt()
[smatch.git] / smatch_array_values.c
blobae0eeda107fd1d2c43c4220e43d1ec64c6a2e0be
1 /*
2 * Copyright (C) 2018 Oracle. All rights reserved.
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, see http://www.gnu.org/copyleft/gpl.txt
18 #include "smatch.h"
19 #include "smatch_extra.h"
21 static int my_id;
23 static int get_vals(void *_db_vals, int argc, char **argv, char **azColName)
25 char **db_vals = _db_vals;
27 *db_vals = alloc_string(argv[0]);
28 return 0;
31 int get_array_rl(struct expression *expr, struct range_list **rl)
33 struct expression *array;
34 struct symbol *type;
35 char buf[128];
36 char *rl_str = NULL;
37 char *name;
39 array = get_array_base(expr);
40 if (!array || array->type != EXPR_SYMBOL || !array->symbol)
41 return 0;
42 if (!(array->symbol->ctype.modifiers & MOD_TOPLEVEL) ||
43 !(array->symbol->ctype.modifiers & MOD_STATIC))
44 return 0;
46 type = get_type(expr);
47 if (!type || type->type != SYM_BASETYPE)
48 return 0;
50 name = expr_to_str(array);
51 snprintf(buf, sizeof(buf), "%s[]", name);
52 free_string(name);
54 run_sql(&get_vals, &rl_str,
55 "select value from sink_info where file = '%s' and static = 1 and sink_name = '%s' and type = %d;",
56 get_filename(), buf, DATA_VALUE);
57 if (!rl_str)
58 return 0;
60 str_to_rl(type, rl_str, rl);
61 free_string(rl_str);
62 return 1;
65 static struct range_list *get_saved_rl(struct symbol *type, char *name)
67 struct range_list *rl;
68 char *str = NULL;
70 cache_sql(&get_vals, &str, "select value from sink_info where file = '%s' and static = 1 and sink_name = '%s' and type = %d;",
71 get_filename(), name, DATA_VALUE);
72 if (!str)
73 return NULL;
75 str_to_rl(type, str, &rl);
76 free_string(str);
78 return rl;
81 static void update_cache(char *name, struct range_list *rl)
83 cache_sql(NULL, NULL, "delete from sink_info where file = '%s' and static = 1 and sink_name = '%s' and type = %d;",
84 get_filename(), name, DATA_VALUE);
85 cache_sql(NULL, NULL, "insert into sink_info values ('%s', 1, '%s', %d, '', '%s');",
86 get_filename(), name, DATA_VALUE, show_rl(rl));
89 static void match_assign(struct expression *expr)
91 struct expression *left, *array;
92 struct symbol *type;
93 struct range_list *orig_rl, *rl;
94 char *name;
95 char buf[128];
97 left = strip_expr(expr->left);
98 if (!is_array(left))
99 return;
100 array = get_array_base(left);
101 if (!array || array->type != EXPR_SYMBOL || !array->symbol)
102 return;
103 if (!(array->symbol->ctype.modifiers & MOD_TOPLEVEL) ||
104 !(array->symbol->ctype.modifiers & MOD_STATIC))
105 return;
106 type = get_type(array);
107 if (!type || type->type != SYM_ARRAY)
108 return;
109 type = get_real_base_type(type);
110 if (!type || type->type != SYM_BASETYPE)
111 return;
113 name = expr_to_str(array);
114 snprintf(buf, sizeof(buf), "%s[]", name);
115 free_string(name);
117 if (expr->op != '=') {
118 rl = alloc_whole_rl(type);
119 } else {
120 get_absolute_rl(expr->right, &rl);
121 rl = cast_rl(type, rl);
122 orig_rl = get_saved_rl(type, buf);
123 rl = rl_union(orig_rl, rl);
126 update_cache(buf, rl);
129 void register_array_values(int id)
131 my_id = id;
133 add_hook(&match_assign, ASSIGNMENT_HOOK);
134 add_hook(&match_assign, GLOBAL_ASSIGNMENT_HOOK);