flow: don't fake an impossible default
[smatch.git] / smatch_mtag_data.c
blob5365e1bbfd4d206defa03f98d80e0f611da52c05
1 /*
2 * Copyright (C) 2016 Oracle.
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
19 * What we're doing here is saving all the possible values for static variables.
20 * Later on we might do globals as well.
24 #include "smatch.h"
25 #include "smatch_slist.h"
26 #include "smatch_extra.h"
28 static int my_id;
29 static struct stree *vals;
31 static int save_rl(void *_rl, int argc, char **argv, char **azColName)
33 unsigned long *rl = _rl;
35 *rl = strtoul(argv[0], NULL, 10);
36 return 0;
39 static struct range_list *select_orig_rl(mtag_t tag, const char *data_name)
41 struct range_list *rl = NULL;
43 mem_sql(&save_rl, &rl, "select value from mtag_data where tag = %lld and data = '%s';",
44 tag, data_name);
45 return rl;
48 static int is_kernel_param(const char *name)
50 struct sm_state *tmp;
51 char buf[256];
54 * I'm ignoring these because otherwise Smatch thinks that kernel
55 * parameters are always set to the default.
59 if (option_project != PROJ_KERNEL)
60 return 0;
62 snprintf(buf, sizeof(buf), "__param_%s.arg", name);
64 FOR_EACH_SM(vals, tmp) {
65 if (strcmp(tmp->name, buf) == 0)
66 return 1;
67 } END_FOR_EACH_SM(tmp);
69 return 0;
72 void insert_mtag_data(mtag_t tag, const char *data_name, int offset, struct range_list *rl)
74 rl = clone_rl_permanent(rl);
76 mem_sql(NULL, NULL, "insert into mtag_data values (%lld, '%s', %d, %d, '%lu');",
77 tag, data_name, offset, DATA_VALUE, (unsigned long)rl);
80 static void extra_mod_hook(const char *name, struct symbol *sym, struct expression *expr, struct smatch_state *state)
82 struct range_list *orig, *new;
83 char *data_name;
84 mtag_t tag;
85 int offset;
87 if (is_kernel_param(name))
88 return;
89 if (!expr_to_mtag_name_offset(expr, &tag, &data_name, &offset))
90 return;
92 orig = select_orig_rl(tag, data_name);
93 new = rl_union(orig, estate_rl(state));
94 insert_mtag_data(tag, data_name, offset, new);
97 static int save_mtag_data(void *_unused, int argc, char **argv, char **azColName)
99 struct range_list *rl;
101 if (argc != 5) {
102 sm_msg("Error saving mtag data");
103 return 0;
106 rl = (struct range_list *)strtoul(argv[4], NULL, 10);
108 if (option_info) {
109 sm_msg("SQL: insert into mtag_data values ('%s', '%s', '%s', '%s', '%s');",
110 argv[0], argv[1], argv[2], argv[3], show_rl(rl));
113 return 0;
116 static void match_end_file(struct symbol_list *sym_list)
118 mem_sql(&save_mtag_data, NULL, "select * from mtag_data;");
121 struct db_info {
122 struct symbol *type;
123 struct range_list *rl;
126 static int get_vals(void *_db_info, int argc, char **argv, char **azColName)
128 struct db_info *db_info = _db_info;
129 struct range_list *tmp;
131 str_to_rl(db_info->type, argv[0], &tmp);
132 if (db_info->rl)
133 db_info->rl = rl_union(db_info->rl, tmp);
134 else
135 db_info->rl = tmp;
137 return 0;
140 int get_db_data_rl(struct expression *expr, struct range_list **rl)
142 const char *name;
143 struct db_info db_info = {};
144 mtag_t tag;
146 if (!get_toplevel_mtag(expr_to_sym(expr), &tag))
147 return 0;
149 name = get_mtag_name_expr(expr);
150 if (!name)
151 return 0;
153 db_info.type = get_type(expr);
154 if (!db_info.type)
155 return 0;
156 run_sql(get_vals, &db_info,
157 "select value from mtag_data where tag = %lld and data = '%s' and type = %d;",
158 tag, name, DATA_VALUE);
159 if (!db_info.rl || is_whole_rl(db_info.rl))
160 return 0;
162 *rl = db_info.rl;
163 return 1;
166 void register_mtag_data(int id)
168 if (!option_info)
169 return;
171 my_id = id;
173 add_extra_mod_hook(&extra_mod_hook);
175 add_hook(&match_end_file, END_FILE_HOOK);