2 * Copyright 2018 Joyent, Inc.
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 * Like lint of old, check that every return value from every function is used.
20 * Casting to (void) will silence this check.
24 #include "smatch_slist.h"
26 static void check_func_return(struct expression
*expr
)
28 struct symbol
*sym
= get_real_base_type(get_type(expr
->fn
));
29 const char *func
= expr_to_str(expr
->fn
);
30 struct statement
*stmt
;
33 sm_error("unknown type for func '%s'", func
);
37 if (expr
->type
!= EXPR_CALL
) {
38 sm_error("func '%s' is not a call site", func
);
43 * There is never any need to check these returns.
45 if (strcmp(func
, "memcpy") == 0 ||
46 strcmp(func
, "memmove") == 0 ||
47 strcmp(func
, "memset") == 0)
51 * Closer to a policy here, but there seems very few cases where it's
52 * useful to check the return value of the standard printf() family
53 * outputting to stdout or stderr.
55 if (strcmp(func
, "printf") == 0 || strcmp(func
, "vprintf") == 0)
58 if (strcmp(func
, "fprintf") == 0 || strcmp(func
, "vfprintf")) {
59 const char *arg0
= expr_to_str(get_argument_from_call_expr(expr
->args
, 0));
62 (strcmp(arg0
, "(&__iob[1])") == 0 ||
63 strcmp(arg0
, "(&__iob[2])") == 0))
68 * Either we got the return type already (direct call),
69 * or we need to go one further (function pointer call)
71 if (sym
== &void_ctype
|| (sym
->type
== SYM_FN
&&
72 get_real_base_type(sym
) == &void_ctype
))
75 stmt
= last_ptr_list((struct ptr_list
*)big_statement_stack
);
77 if (stmt
->type
== STMT_EXPRESSION
&& stmt
->expression
== expr
)
78 sm_error("unchecked function return '%s'", expr_to_str(expr
->fn
));
81 void check_all_func_returns(int id
)
83 if (option_project
!= PROJ_ILLUMOS_KERNEL
&&
84 option_project
!= PROJ_ILLUMOS_USER
)
87 add_hook(&check_func_return
, FUNCTION_CALL_HOOK
);