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
19 #include "smatch_slist.h"
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
;
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
);
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
);
65 sm
= get_sm_state_expr(my_id
, expr
);
69 return clone_slist(sm
->possible
);
72 static void match_assignment(struct expression
*expr
)
74 struct state_list
*slist
;
80 slist
= get_strings(strip_expr(expr
->right
));
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
);
91 void register_strings(int 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
);