Module Name:    src
Committed By:   rillig
Date:           Sun Aug 15 14:26:40 UTC 2021

Modified Files:
        src/tests/usr.bin/xlint/lint1: msg_346.c msg_346.exp
        src/usr.bin/xlint/lint1: tree.c

Log Message:
lint: extend check for unconst functions

The functions memchr, strpbrk, strrchr and strstr effectively remove the
const qualifier of their first argument, just like strchr.


To generate a diff of this commit:
cvs rdiff -u -r1.2 -r1.3 src/tests/usr.bin/xlint/lint1/msg_346.c \
    src/tests/usr.bin/xlint/lint1/msg_346.exp
cvs rdiff -u -r1.335 -r1.336 src/usr.bin/xlint/lint1/tree.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/tests/usr.bin/xlint/lint1/msg_346.c
diff -u src/tests/usr.bin/xlint/lint1/msg_346.c:1.2 src/tests/usr.bin/xlint/lint1/msg_346.c:1.3
--- src/tests/usr.bin/xlint/lint1/msg_346.c:1.2	Sun Aug 15 14:00:27 2021
+++ src/tests/usr.bin/xlint/lint1/msg_346.c	Sun Aug 15 14:26:39 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: msg_346.c,v 1.2 2021/08/15 14:00:27 rillig Exp $	*/
+/*	$NetBSD: msg_346.c,v 1.3 2021/08/15 14:26:39 rillig Exp $	*/
 # 3 "msg_346.c"
 
 // Test for message: call to '%s' effectively discards 'const' from argument [346]
@@ -40,14 +40,14 @@ example(void)
 void
 all_functions(void)
 {
-	/* TODO: expect+1: warning: call to 'memchr' effectively discards 'const' from argument [346] */
+	/* expect+1: warning: call to 'memchr' effectively discards 'const' from argument [346] */
 	take_char_ptr(memchr("string", 'c', 7));
 	/* expect+1: warning: call to 'strchr' effectively discards 'const' from argument [346] */
 	take_char_ptr(strchr("string", 'c'));
-	/* TODO: expect+1: warning: call to 'strpbrk' effectively discards 'const' from argument [346] */
+	/* expect+1: warning: call to 'strpbrk' effectively discards 'const' from argument [346] */
 	take_char_ptr(strpbrk("string", "c"));
-	/* TODO: expect+1: warning: call to 'strrchr' effectively discards 'const' from argument [346] */
+	/* expect+1: warning: call to 'strrchr' effectively discards 'const' from argument [346] */
 	take_char_ptr(strrchr("string", 'c'));
-	/* TODO: expect+1: warning: call to 'strstr' effectively discards 'const' from argument [346] */
+	/* expect+1: warning: call to 'strstr' effectively discards 'const' from argument [346] */
 	take_char_ptr(strstr("string", "c"));
 }
Index: src/tests/usr.bin/xlint/lint1/msg_346.exp
diff -u src/tests/usr.bin/xlint/lint1/msg_346.exp:1.2 src/tests/usr.bin/xlint/lint1/msg_346.exp:1.3
--- src/tests/usr.bin/xlint/lint1/msg_346.exp:1.2	Sun Aug 15 14:00:27 2021
+++ src/tests/usr.bin/xlint/lint1/msg_346.exp	Sun Aug 15 14:26:39 2021
@@ -1,4 +1,8 @@
 msg_346.c(26): warning: call to 'strchr' effectively discards 'const' from argument [346]
 msg_346.c(32): warning: call to 'strchr' effectively discards 'const' from argument [346]
 msg_346.c(37): warning: call to 'strchr' effectively discards 'const' from argument [346]
+msg_346.c(44): warning: call to 'memchr' effectively discards 'const' from argument [346]
 msg_346.c(46): warning: call to 'strchr' effectively discards 'const' from argument [346]
+msg_346.c(48): warning: call to 'strpbrk' effectively discards 'const' from argument [346]
+msg_346.c(50): warning: call to 'strrchr' effectively discards 'const' from argument [346]
+msg_346.c(52): warning: call to 'strstr' effectively discards 'const' from argument [346]

Index: src/usr.bin/xlint/lint1/tree.c
diff -u src/usr.bin/xlint/lint1/tree.c:1.335 src/usr.bin/xlint/lint1/tree.c:1.336
--- src/usr.bin/xlint/lint1/tree.c:1.335	Sun Aug 15 13:08:19 2021
+++ src/usr.bin/xlint/lint1/tree.c	Sun Aug 15 14:26:39 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: tree.c,v 1.335 2021/08/15 13:08:19 rillig Exp $	*/
+/*	$NetBSD: tree.c,v 1.336 2021/08/15 14:26:39 rillig Exp $	*/
 
 /*
  * Copyright (c) 1994, 1995 Jochen Pohl
@@ -37,7 +37,7 @@
 
 #include <sys/cdefs.h>
 #if defined(__RCSID) && !defined(lint)
-__RCSID("$NetBSD: tree.c,v 1.335 2021/08/15 13:08:19 rillig Exp $");
+__RCSID("$NetBSD: tree.c,v 1.336 2021/08/15 14:26:39 rillig Exp $");
 #endif
 
 #include <float.h>
@@ -1349,12 +1349,27 @@ check_pointer_comparison(op_t op, const 
 }
 
 static bool
-is_direct_function_call(const tnode_t *tn, const char *name)
+is_direct_function_call(const tnode_t *tn, const char **out_name)
 {
-	return tn->tn_op == CALL &&
-	       tn->tn_left->tn_op == ADDR &&
-	       tn->tn_left->tn_left->tn_op == NAME &&
-	       strcmp(tn->tn_left->tn_left->tn_sym->s_name, name) == 0;
+
+	if (!(tn->tn_op == CALL &&
+	      tn->tn_left->tn_op == ADDR &&
+	      tn->tn_left->tn_left->tn_op == NAME))
+		return false;
+
+	*out_name = tn->tn_left->tn_left->tn_sym->s_name;
+	return true;
+}
+
+static bool
+is_unconst_function(const char *name)
+{
+
+	return strcmp(name, "memchr") == 0 ||
+	       strcmp(name, "strchr") == 0 ||
+	       strcmp(name, "strpbrk") == 0 ||
+	       strcmp(name, "strrchr") == 0 ||
+	       strcmp(name, "strstr") == 0;
 }
 
 static bool
@@ -1385,23 +1400,31 @@ is_const_char_pointer(const tnode_t *tn)
 }
 
 static bool
-is_strchr_arg_const(const tnode_t *tn)
+is_first_arg_const(const tnode_t *tn)
 {
-	return tn->tn_right->tn_op == PUSH &&
-	       tn->tn_right->tn_right->tn_op == PUSH &&
-	       tn->tn_right->tn_right->tn_right == NULL &&
-	       is_const_char_pointer(tn->tn_right->tn_right->tn_left);
+	const tnode_t *an;
+
+	an = tn->tn_right;
+	if (an == NULL)
+		return false;
+
+	while (an->tn_right != NULL)
+		an = an->tn_right;
+	return is_const_char_pointer(an->tn_left);
 }
 
 static void
-check_unconst_strchr(const type_t *lstp,
-		     const tnode_t *rn, const type_t *rstp)
+check_unconst_function(const type_t *lstp,
+		       const tnode_t *rn, const type_t *rstp)
 {
+	const char *function_name;
+
 	if (lstp->t_tspec == CHAR && !lstp->t_const &&
-	    is_direct_function_call(rn, "strchr") &&
-	    is_strchr_arg_const(rn)) {
+	    is_direct_function_call(rn, &function_name) &&
+	    is_unconst_function(function_name) &&
+	    is_first_arg_const(rn)) {
 		/* call to '%s' effectively discards 'const' from argument */
-		warning(346, "strchr");
+		warning(346, function_name);
 	}
 }
 
@@ -1490,7 +1513,7 @@ check_assign_types_compatible(op_t op, i
 		}
 
 		if (!tflag)
-			check_unconst_strchr(lstp, rn, rstp);
+			check_unconst_function(lstp, rn, rstp);
 
 		return true;
 	}

Reply via email to