core: silence some false positives from parsing invalid code
[smatch.git] / smatch_strings.c
blobf4ee523319f7be8dec664af85d7385e55bfe74f5
1 /*
2 * Copyright (C) 2015 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
18 #include "smatch.h"
19 #include "smatch_slist.h"
21 static int my_id;
23 static void match_strcpy(const char *fn, struct expression *expr, void *unused)
25 struct expression *dest, *src;
27 dest = get_argument_from_call_expr(expr->args, 0);
28 src = get_argument_from_call_expr(expr->args, 1);
29 src = strip_expr(src);
30 if (src->type == EXPR_STRING)
31 set_state_expr(my_id, dest, alloc_state_str(src->string->data));
34 struct state_list *get_strings(struct expression *expr)
36 struct state_list *ret = NULL;
37 struct smatch_state *state;
38 struct sm_state *sm;
40 expr = strip_expr(expr);
41 if (expr->type == EXPR_STRING) {
42 state = alloc_state_str(expr->string->data);
43 sm = alloc_sm_state(my_id, expr->string->data, NULL, state);
44 add_ptr_list(&ret, sm);
45 return ret;
48 if (expr->type == EXPR_CONDITIONAL ||
49 expr->type == EXPR_SELECT) {
50 struct state_list *true_strings = NULL;
51 struct state_list *false_strings = NULL;
53 if (known_condition_true(expr->conditional))
54 return get_strings(expr->cond_true);
55 if (known_condition_false(expr->conditional))
56 return get_strings(expr->cond_false);
58 true_strings = get_strings(expr->cond_true);
59 false_strings = get_strings(expr->cond_false);
60 concat_ptr_list((struct ptr_list *)true_strings, (struct ptr_list **)&false_strings);
61 free_slist(&true_strings);
62 return false_strings;
65 sm = get_sm_state_expr(my_id, expr);
66 if (!sm)
67 return NULL;
69 return clone_slist(sm->possible);
72 static void match_assignment(struct expression *expr)
74 struct state_list *slist;
75 struct sm_state *sm;
77 if (expr->op != '=')
78 return;
80 slist = get_strings(strip_expr(expr->right));
81 if (!slist)
82 return;
84 if (ptr_list_size((struct ptr_list *)slist) == 1) {
85 sm = first_ptr_list((struct ptr_list *)slist);
86 set_state_expr(my_id, expr->left, sm->state);
87 return;
91 void register_strings(int id)
93 my_id = id;
95 add_function_hook("strcpy", &match_strcpy, NULL);
96 add_function_hook("strlcpy", &match_strcpy, NULL);
97 add_function_hook("strncpy", &match_strcpy, NULL);
99 add_hook(&match_assignment, ASSIGNMENT_HOOK);