Sat Apr 15 10:32:46 2023 UTC ()
lint: extract checking the return value to separate function

No functional change.


(rillig)
diff -r1.151 -r1.152 src/usr.bin/xlint/lint1/func.c

cvs diff -r1.151 -r1.152 src/usr.bin/xlint/lint1/func.c (expand / switch to unified diff)

--- src/usr.bin/xlint/lint1/func.c 2023/03/28 20:01:21 1.151
+++ src/usr.bin/xlint/lint1/func.c 2023/04/15 10:32:46 1.152
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: func.c,v 1.151 2023/03/28 20:01:21 rillig Exp $ */ 1/* $NetBSD: func.c,v 1.152 2023/04/15 10:32:46 rillig Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1994, 1995 Jochen Pohl 4 * Copyright (c) 1994, 1995 Jochen Pohl
5 * All Rights Reserved. 5 * All Rights Reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -27,27 +27,27 @@ @@ -27,27 +27,27 @@
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */ 32 */
33 33
34#if HAVE_NBTOOL_CONFIG_H 34#if HAVE_NBTOOL_CONFIG_H
35#include "nbtool_config.h" 35#include "nbtool_config.h"
36#endif 36#endif
37 37
38#include <sys/cdefs.h> 38#include <sys/cdefs.h>
39#if defined(__RCSID) 39#if defined(__RCSID)
40__RCSID("$NetBSD: func.c,v 1.151 2023/03/28 20:01:21 rillig Exp $"); 40__RCSID("$NetBSD: func.c,v 1.152 2023/04/15 10:32:46 rillig Exp $");
41#endif 41#endif
42 42
43#include <stdlib.h> 43#include <stdlib.h>
44#include <string.h> 44#include <string.h>
45 45
46#include "lint1.h" 46#include "lint1.h"
47#include "cgram.h" 47#include "cgram.h"
48 48
49/* 49/*
50 * Contains a pointer to the symbol table entry of the current function 50 * Contains a pointer to the symbol table entry of the current function
51 * definition. 51 * definition.
52 */ 52 */
53sym_t *funcsym; 53sym_t *funcsym;
@@ -1037,38 +1037,61 @@ do_continue(void) @@ -1037,38 +1037,61 @@ do_continue(void)
1037 if (cs == NULL) { 1037 if (cs == NULL) {
1038 /* continue outside loop */ 1038 /* continue outside loop */
1039 error(209); 1039 error(209);
1040 } else { 1040 } else {
1041 /* TODO: only if reachable, for symmetry with c_break */ 1041 /* TODO: only if reachable, for symmetry with c_break */
1042 cs->c_continue = true; 1042 cs->c_continue = true;
1043 } 1043 }
1044 1044
1045 check_statement_reachable(); 1045 check_statement_reachable();
1046 1046
1047 set_reached(false); 1047 set_reached(false);
1048} 1048}
1049 1049
 1050static void
 1051check_return_value(bool sys, tnode_t *tn)
 1052{
 1053 /* Create a temporary node for the left side */
 1054 tnode_t *ln = expr_zero_alloc(sizeof(*ln));
 1055 ln->tn_op = NAME;
 1056 ln->tn_type = expr_unqualified_type(funcsym->s_type->t_subt);
 1057 ln->tn_lvalue = true;
 1058 ln->tn_sym = funcsym; /* better than nothing */
 1059
 1060 tnode_t *retn = build_binary(ln, RETURN, sys, tn);
 1061
 1062 if (retn != NULL) {
 1063 const tnode_t *rn = retn->tn_right;
 1064 while (rn->tn_op == CVT || rn->tn_op == PLUS)
 1065 rn = rn->tn_left;
 1066 if (rn->tn_op == ADDR && rn->tn_left->tn_op == NAME &&
 1067 rn->tn_left->tn_sym->s_scl == AUTO) {
 1068 /* '%s' returns pointer to automatic object */
 1069 warning(302, funcsym->s_name);
 1070 }
 1071 }
 1072
 1073 expr(retn, true, false, true, false);
 1074}
 1075
1050/* 1076/*
1051 * T_RETURN T_SEMI 1077 * T_RETURN T_SEMI
1052 * T_RETURN expr T_SEMI 1078 * T_RETURN expr T_SEMI
1053 */ 1079 */
1054void 1080void
1055do_return(bool sys, tnode_t *tn) 1081do_return(bool sys, tnode_t *tn)
1056{ 1082{
1057 tnode_t *ln, *rn; 1083 control_statement *cs = cstmt;
1058 control_statement *cs; 
1059 op_t op; 
1060 1084
1061 cs = cstmt; 
1062 if (cs == NULL) { 1085 if (cs == NULL) {
1063 /* syntax error '%s' */ 1086 /* syntax error '%s' */
1064 error(249, "return outside function"); 1087 error(249, "return outside function");
1065 return; 1088 return;
1066 } 1089 }
1067 1090
1068 for (; cs->c_surrounding != NULL; cs = cs->c_surrounding) 1091 for (; cs->c_surrounding != NULL; cs = cs->c_surrounding)
1069 continue; 1092 continue;
1070 1093
1071 if (tn != NULL) 1094 if (tn != NULL)
1072 cs->c_had_return_value = true; 1095 cs->c_had_return_value = true;
1073 else 1096 else
1074 cs->c_had_return_noval = true; 1097 cs->c_had_return_noval = true;
@@ -1078,56 +1101,31 @@ do_return(bool sys, tnode_t *tn) @@ -1078,56 +1101,31 @@ do_return(bool sys, tnode_t *tn)
1078 error(213, funcsym->s_name); 1101 error(213, funcsym->s_name);
1079 expr_free_all(); 1102 expr_free_all();
1080 tn = NULL; 1103 tn = NULL;
1081 } else if (tn == NULL && funcsym->s_type->t_subt->t_tspec != VOID) { 1104 } else if (tn == NULL && funcsym->s_type->t_subt->t_tspec != VOID) {
1082 /* 1105 /*
1083 * Assume that the function has a return value only if it 1106 * Assume that the function has a return value only if it
1084 * is explicitly declared. 1107 * is explicitly declared.
1085 */ 1108 */
1086 if (!funcsym->s_return_type_implicit_int) 1109 if (!funcsym->s_return_type_implicit_int)
1087 /* function '%s' expects to return value */ 1110 /* function '%s' expects to return value */
1088 warning(214, funcsym->s_name); 1111 warning(214, funcsym->s_name);
1089 } 1112 }
1090 1113
1091 if (tn != NULL) { 1114 if (tn != NULL)
1092 1115 check_return_value(sys, tn);
1093 /* Create a temporary node for the left side */ 1116 else
1094 ln = expr_zero_alloc(sizeof(*ln)); 
1095 ln->tn_op = NAME; 
1096 ln->tn_type = expr_unqualified_type(funcsym->s_type->t_subt); 
1097 ln->tn_lvalue = true; 
1098 ln->tn_sym = funcsym; /* better than nothing */ 
1099 
1100 tn = build_binary(ln, RETURN, sys, tn); 
1101 
1102 if (tn != NULL) { 
1103 rn = tn->tn_right; 
1104 while ((op = rn->tn_op) == CVT || op == PLUS) 
1105 rn = rn->tn_left; 
1106 if (rn->tn_op == ADDR && rn->tn_left->tn_op == NAME && 
1107 rn->tn_left->tn_sym->s_scl == AUTO) { 
1108 /* '%s' returns pointer to automatic object */ 
1109 warning(302, funcsym->s_name); 
1110 } 
1111 } 
1112 
1113 expr(tn, true, false, true, false); 
1114 
1115 } else { 
1116 
1117 check_statement_reachable(); 1117 check_statement_reachable();
1118 1118
1119 } 
1120 
1121 set_reached(false); 1119 set_reached(false);
1122} 1120}
1123 1121
1124/* 1122/*
1125 * Do some cleanup after a global declaration or definition. 1123 * Do some cleanup after a global declaration or definition.
1126 * Especially remove information about unused lint comments. 1124 * Especially remove information about unused lint comments.
1127 */ 1125 */
1128void 1126void
1129global_clean_up_decl(bool silent) 1127global_clean_up_decl(bool silent)
1130{ 1128{
1131 1129
1132 if (nargusg != -1) { 1130 if (nargusg != -1) {
1133 if (!silent) { 1131 if (!silent) {