Print this page
12724 update smatch to 0.6.1-rc1-il-5
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/tools/smatch/src/check_all_func_returns.c
+++ new/usr/src/tools/smatch/src/check_all_func_returns.c
1 1 /*
2 2 * Copyright 2018 Joyent, Inc.
3 3 *
4 4 * This program is free software; you can redistribute it and/or
5 5 * modify it under the terms of the GNU General Public License
6 6 * as published by the Free Software Foundation; either version 2
7 7 * of the License, or (at your option) any later version.
8 8 *
9 9 * This program is distributed in the hope that it will be useful,
10 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 * GNU General Public License for more details.
13 13 *
14 14 * You should have received a copy of the GNU General Public License
15 15 * along with this program; if not, see http://www.gnu.org/copyleft/gpl.txt
16 16 */
17 17
18 18 /*
19 19 * Like lint of old, check that every return value from every function is used.
20 20 * Casting to (void) will silence this check.
21 21 */
22 22
23 23 #include "smatch.h"
24 24 #include "smatch_slist.h"
25 25
26 26 static void check_func_return(struct expression *expr)
27 27 {
28 28 struct symbol *sym = get_real_base_type(get_type(expr->fn));
29 29 const char *func = expr_to_str(expr->fn);
30 30 struct statement *stmt;
31 31
32 32 if (sym == NULL) {
33 33 sm_error("unknown type for func '%s'", func);
34 34 return;
35 35 }
36 36
37 37 if (expr->type != EXPR_CALL) {
38 38 sm_error("func '%s' is not a call site", func);
39 39 return;
40 40 }
41 41
42 42 /*
43 43 * There is never any need to check these returns.
44 44 */
45 45 if (strcmp(func, "memcpy") == 0 ||
46 46 strcmp(func, "memmove") == 0 ||
47 47 strcmp(func, "memset") == 0)
48 48 return;
49 49
50 50 /*
51 51 * Closer to a policy here, but there seems very few cases where it's
52 52 * useful to check the return value of the standard printf() family
53 53 * outputting to stdout or stderr.
54 54 */
55 55 if (strcmp(func, "printf") == 0 || strcmp(func, "vprintf") == 0)
56 56 return;
57 57
58 58 if (strcmp(func, "fprintf") == 0 || strcmp(func, "vfprintf")) {
59 59 const char *arg0 = expr_to_str(get_argument_from_call_expr(expr->args, 0));
60 60
61 61 if (arg0 != NULL &&
62 62 (strcmp(arg0, "(&__iob[1])") == 0 ||
63 63 strcmp(arg0, "(&__iob[2])") == 0))
64 64 return;
65 65 }
66 66
↓ open down ↓ |
66 lines elided |
↑ open up ↑ |
67 67 /*
68 68 * Either we got the return type already (direct call),
69 69 * or we need to go one further (function pointer call)
70 70 */
71 71 if (sym == &void_ctype || (sym->type == SYM_FN &&
72 72 get_real_base_type(sym) == &void_ctype))
73 73 return;
74 74
75 75 stmt = last_ptr_list((struct ptr_list *)big_statement_stack);
76 76
77 - if (stmt->type == STMT_EXPRESSION && stmt->expression == expr)
77 + if (stmt && stmt->type == STMT_EXPRESSION && stmt->expression == expr)
78 78 sm_error("unchecked function return '%s'", expr_to_str(expr->fn));
79 79 }
80 80
81 81 void check_all_func_returns(int id)
82 82 {
83 83 if (option_project != PROJ_ILLUMOS_KERNEL &&
84 84 option_project != PROJ_ILLUMOS_USER)
85 85 return;
86 86
87 87 add_hook(&check_func_return, FUNCTION_CALL_HOOK);
88 88 }
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX