1 /*
2  * Copyright (C) 2009 Dan Carpenter.
3  *
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.
8  *
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.
13  *
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
16  */
17 
18 #include "smatch.h"
19 #include "smatch_slist.h"
20 
21 STATE(ignore);
22 static struct stree *ignored;
23 static struct stree *ignored_from_file;
24 
add_ignore(int owner,const char * name,struct symbol * sym)25 void add_ignore(int owner, const char *name, struct symbol *sym)
26 {
27 	set_state_stree(&ignored, owner, name, sym, &ignore);
28 }
29 
is_ignored(int owner,const char * name,struct symbol * sym)30 int is_ignored(int owner, const char *name, struct symbol *sym)
31 {
32 	return !!get_state_stree(ignored, owner, name, sym);
33 }
34 
add_ignore_expr(int owner,struct expression * expr)35 void add_ignore_expr(int owner, struct expression *expr)
36 {
37 	struct symbol *sym;
38 	char *name;
39 
40 	name = expr_to_str_sym(expr, &sym);
41 	if (!name || !sym)
42 		return;
43 	add_ignore(owner, name, sym);
44 	free_string(name);
45 }
46 
is_ignored_expr(int owner,struct expression * expr)47 int is_ignored_expr(int owner, struct expression *expr)
48 {
49 	struct symbol *sym;
50 	char *name;
51 	int ret;
52 
53 	name = expr_to_str_sym(expr, &sym);
54 	if (!name && !sym)
55 		return 0;
56 	ret = is_ignored(owner, name, sym);
57 	free_string(name);
58 	if (ret)
59 		return true;
60 
61 	name = get_macro_name(expr->pos);
62 	if (name && get_state_stree(ignored_from_file, owner, name, NULL))
63 		return true;
64 
65 	name = get_function();
66 	if (name && get_state_stree(ignored_from_file, owner, name, NULL))
67 		return true;
68 
69 	return false;
70 }
71 
clear_ignores(void)72 static void clear_ignores(void)
73 {
74 	if (__inline_fn)
75 		return;
76 	free_stree(&ignored);
77 }
78 
load_ignores(void)79 static void load_ignores(void)
80 {
81 	struct token *token;
82 	const char *name, *str;
83 	int owner;
84 	char buf[64];
85 
86 	snprintf(buf, sizeof(buf), "%s.ignored_warnings", option_project_str);
87 	token = get_tokens_file(buf);
88 	if (!token)
89 		return;
90 	if (token_type(token) != TOKEN_STREAMBEGIN)
91 		return;
92 	token = token->next;
93 	while (token_type(token) != TOKEN_STREAMEND) {
94 		if (token_type(token) != TOKEN_IDENT)
95 			break;
96 		name = show_ident(token->ident);
97 		token = token->next;
98 		owner = id_from_name(name);
99 
100 		if (token_type(token) != TOKEN_IDENT)
101 			break;
102 		str = show_ident(token->ident);
103 		token = token->next;
104 
105 		set_state_stree_perm(&ignored_from_file, owner, str, NULL, &ignore);
106 	}
107 	clear_token_alloc();
108 }
109 
register_smatch_ignore(int id)110 void register_smatch_ignore(int id)
111 {
112 	add_hook(&clear_ignores, AFTER_FUNC_HOOK);
113 	load_ignores();
114 }
115