2 * Copyright 2023 Linaro Ltd.
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 * Once you've used an fd one time, you can't use it again.
20 * But the problem is that an fd is just an int. It might be nice if we
21 * tracked this in smatch_units.c. Another hacky thing (not nice) might
22 * be to mark it as freed after use so it could show up as a use after
23 * free. But instead I am doing this.
28 #include "smatch_slist.h"
34 static void match_fget(struct expression
*expr
, const char *name
, struct symbol
*sym
, void *data
)
37 struct sm_state
*sm
= get_sm_state(my_id
, name
, sym
);
38 sm_msg("%s: expr='%s' name='%s' sm='%s'", __func__
, expr_to_str(expr
), name
, show_sm(sm
));
40 if (has_possible_state(my_id
, name
, sym
, &fget
))
41 sm_warning("double fget(): '%s'", name
);
42 set_state(my_id
, name
, sym
, &fget
);
45 static void return_info_callback(int return_id
, char *return_ranges
,
46 struct expression
*returned_expr
,
48 const char *printed_name
,
51 sql_insert_return_states(return_id
, return_ranges
,
53 param
, printed_name
, "");
56 static void caller_info_callback(struct expression
*call
, int param
, char *printed_name
, struct sm_state
*sm
)
58 if (strcmp(printed_name
, "$") != 0)
60 sm_warning("fd re-used after fget(): '%s'", sm
->name
);
63 void check_double_fget(int id
)
65 if (option_project
!= PROJ_KERNEL
)
70 add_function_param_key_hook("fget", &match_fget
, 0, "$", NULL
);
71 add_function_param_key_hook("fdget", &match_fget
, 0, "$", NULL
);
72 add_return_info_callback(my_id
, return_info_callback
);
73 select_return_param_key(FGET
, &match_fget
);
75 add_caller_info_callback(my_id
, caller_info_callback
);