Module Name:    src
Committed By:   rillig
Date:           Fri Mar  1 19:39:29 UTC 2024

Modified Files:
        src/distrib/sets/lists/tests: mi
        src/tests/usr.bin/xlint/lint1: t_usage.sh
        src/usr.bin/xlint/lint1: Makefile err.c externs1.h tree.c
Added Files:
        src/tests/usr.bin/xlint/lint1: msg_357.c msg_358.c msg_359.c msg_360.c
            msg_361.c msg_362.c msg_363.c msg_364.c msg_365.c msg_366.c
            msg_367.c msg_368.c msg_369.c msg_370.c msg_371.c msg_372.c
            msg_373.c msg_374.c msg_375.c

Log Message:
lint: test format strings from snprintb calls

The functions snprintb and snprintb_m are specific to NetBSD, and their
format strings are tricky to get correct.  Provide some assistance in
catching the most common mistakes.


To generate a diff of this commit:
cvs rdiff -u -r1.1306 -r1.1307 src/distrib/sets/lists/tests/mi
cvs rdiff -u -r0 -r1.1 src/tests/usr.bin/xlint/lint1/msg_357.c \
    src/tests/usr.bin/xlint/lint1/msg_358.c \
    src/tests/usr.bin/xlint/lint1/msg_359.c \
    src/tests/usr.bin/xlint/lint1/msg_360.c \
    src/tests/usr.bin/xlint/lint1/msg_361.c \
    src/tests/usr.bin/xlint/lint1/msg_362.c \
    src/tests/usr.bin/xlint/lint1/msg_363.c \
    src/tests/usr.bin/xlint/lint1/msg_364.c \
    src/tests/usr.bin/xlint/lint1/msg_365.c \
    src/tests/usr.bin/xlint/lint1/msg_366.c \
    src/tests/usr.bin/xlint/lint1/msg_367.c \
    src/tests/usr.bin/xlint/lint1/msg_368.c \
    src/tests/usr.bin/xlint/lint1/msg_369.c \
    src/tests/usr.bin/xlint/lint1/msg_370.c \
    src/tests/usr.bin/xlint/lint1/msg_371.c \
    src/tests/usr.bin/xlint/lint1/msg_372.c \
    src/tests/usr.bin/xlint/lint1/msg_373.c \
    src/tests/usr.bin/xlint/lint1/msg_374.c \
    src/tests/usr.bin/xlint/lint1/msg_375.c
cvs rdiff -u -r1.15 -r1.16 src/tests/usr.bin/xlint/lint1/t_usage.sh
cvs rdiff -u -r1.103 -r1.104 src/usr.bin/xlint/lint1/Makefile
cvs rdiff -u -r1.225 -r1.226 src/usr.bin/xlint/lint1/err.c
cvs rdiff -u -r1.216 -r1.217 src/usr.bin/xlint/lint1/externs1.h
cvs rdiff -u -r1.605 -r1.606 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/distrib/sets/lists/tests/mi
diff -u src/distrib/sets/lists/tests/mi:1.1306 src/distrib/sets/lists/tests/mi:1.1307
--- src/distrib/sets/lists/tests/mi:1.1306	Mon Feb 19 04:30:38 2024
+++ src/distrib/sets/lists/tests/mi	Fri Mar  1 19:39:28 2024
@@ -1,4 +1,4 @@
-# $NetBSD: mi,v 1.1306 2024/02/19 04:30:38 riastradh Exp $
+# $NetBSD: mi,v 1.1307 2024/03/01 19:39:28 rillig Exp $
 #
 # Note: don't delete entries from here - mark them as "obsolete" instead.
 #
@@ -7471,6 +7471,25 @@
 ./usr/tests/usr.bin/xlint/lint1/msg_354.c			tests-usr.bin-tests	compattestfile,atf
 ./usr/tests/usr.bin/xlint/lint1/msg_355.c			tests-usr.bin-tests	compattestfile,atf
 ./usr/tests/usr.bin/xlint/lint1/msg_356.c			tests-usr.bin-tests	compattestfile,atf
+./usr/tests/usr.bin/xlint/lint1/msg_357.c			tests-usr.bin-tests	compattestfile,atf
+./usr/tests/usr.bin/xlint/lint1/msg_358.c			tests-usr.bin-tests	compattestfile,atf
+./usr/tests/usr.bin/xlint/lint1/msg_359.c			tests-usr.bin-tests	compattestfile,atf
+./usr/tests/usr.bin/xlint/lint1/msg_360.c			tests-usr.bin-tests	compattestfile,atf
+./usr/tests/usr.bin/xlint/lint1/msg_361.c			tests-usr.bin-tests	compattestfile,atf
+./usr/tests/usr.bin/xlint/lint1/msg_362.c			tests-usr.bin-tests	compattestfile,atf
+./usr/tests/usr.bin/xlint/lint1/msg_363.c			tests-usr.bin-tests	compattestfile,atf
+./usr/tests/usr.bin/xlint/lint1/msg_364.c			tests-usr.bin-tests	compattestfile,atf
+./usr/tests/usr.bin/xlint/lint1/msg_365.c			tests-usr.bin-tests	compattestfile,atf
+./usr/tests/usr.bin/xlint/lint1/msg_366.c			tests-usr.bin-tests	compattestfile,atf
+./usr/tests/usr.bin/xlint/lint1/msg_367.c			tests-usr.bin-tests	compattestfile,atf
+./usr/tests/usr.bin/xlint/lint1/msg_368.c			tests-usr.bin-tests	compattestfile,atf
+./usr/tests/usr.bin/xlint/lint1/msg_369.c			tests-usr.bin-tests	compattestfile,atf
+./usr/tests/usr.bin/xlint/lint1/msg_370.c			tests-usr.bin-tests	compattestfile,atf
+./usr/tests/usr.bin/xlint/lint1/msg_371.c			tests-usr.bin-tests	compattestfile,atf
+./usr/tests/usr.bin/xlint/lint1/msg_372.c			tests-usr.bin-tests	compattestfile,atf
+./usr/tests/usr.bin/xlint/lint1/msg_373.c			tests-usr.bin-tests	compattestfile,atf
+./usr/tests/usr.bin/xlint/lint1/msg_374.c			tests-usr.bin-tests	compattestfile,atf
+./usr/tests/usr.bin/xlint/lint1/msg_375.c			tests-usr.bin-tests	compattestfile,atf
 ./usr/tests/usr.bin/xlint/lint1/op_colon.c			tests-usr.bin-tests	compattestfile,atf
 ./usr/tests/usr.bin/xlint/lint1/op_colon.exp			tests-obsolete		obsolete,atf
 ./usr/tests/usr.bin/xlint/lint1/op_shl_lp64.c			tests-usr.bin-tests	compattestfile,atf

Index: src/tests/usr.bin/xlint/lint1/t_usage.sh
diff -u src/tests/usr.bin/xlint/lint1/t_usage.sh:1.15 src/tests/usr.bin/xlint/lint1/t_usage.sh:1.16
--- src/tests/usr.bin/xlint/lint1/t_usage.sh:1.15	Sat Feb  3 20:10:11 2024
+++ src/tests/usr.bin/xlint/lint1/t_usage.sh	Fri Mar  1 19:39:29 2024
@@ -1,4 +1,4 @@
-# $NetBSD: t_usage.sh,v 1.15 2024/02/03 20:10:11 rillig Exp $
+# $NetBSD: t_usage.sh,v 1.16 2024/03/01 19:39:29 rillig Exp $
 #
 # Copyright (c) 2023 The NetBSD Foundation, Inc.
 # All rights reserved.
@@ -39,13 +39,13 @@ suppress_messages_body()
 
 	# The largest known message.
 	atf_check \
-	    "$lint1" -X 355 code.c /dev/null
+	    "$lint1" -X 375 code.c /dev/null
 
 	# Larger than the largest known message.
 	atf_check \
 	    -s 'exit:1' \
-	    -e "inline:lint1: invalid message ID '357'\n" \
-	    "$lint1" -X 357 code.c /dev/null
+	    -e "inline:lint1: invalid message ID '376'\n" \
+	    "$lint1" -X 376 code.c /dev/null
 
 	# Whitespace is not allowed before a message ID.
 	atf_check \

Index: src/usr.bin/xlint/lint1/Makefile
diff -u src/usr.bin/xlint/lint1/Makefile:1.103 src/usr.bin/xlint/lint1/Makefile:1.104
--- src/usr.bin/xlint/lint1/Makefile:1.103	Tue Feb  6 22:47:21 2024
+++ src/usr.bin/xlint/lint1/Makefile	Fri Mar  1 19:39:28 2024
@@ -1,10 +1,10 @@
-#	$NetBSD: Makefile,v 1.103 2024/02/06 22:47:21 rillig Exp $
+#	$NetBSD: Makefile,v 1.104 2024/03/01 19:39:28 rillig Exp $
 
 .include <bsd.own.mk>
 
 PROG=		lint1
 SRCS=		cgram.y \
-		ckbool.c ckctype.c ckgetopt.c debug.c \
+		ckbool.c ckctype.c ckgetopt.c cksnprintb.c debug.c \
 		decl.c emit.c emit1.c err.c func.c init.c inittyp.c lex.c \
 		main1.c mem.c mem1.c oper.c scan.l tree.c tyname.c
 

Index: src/usr.bin/xlint/lint1/err.c
diff -u src/usr.bin/xlint/lint1/err.c:1.225 src/usr.bin/xlint/lint1/err.c:1.226
--- src/usr.bin/xlint/lint1/err.c:1.225	Tue Feb  6 22:47:21 2024
+++ src/usr.bin/xlint/lint1/err.c	Fri Mar  1 19:39:28 2024
@@ -1,4 +1,4 @@
-/*	$NetBSD: err.c,v 1.225 2024/02/06 22:47:21 rillig Exp $	*/
+/*	$NetBSD: err.c,v 1.226 2024/03/01 19:39:28 rillig Exp $	*/
 
 /*
  * Copyright (c) 1994, 1995 Jochen Pohl
@@ -37,7 +37,7 @@
 
 #include <sys/cdefs.h>
 #if defined(__RCSID)
-__RCSID("$NetBSD: err.c,v 1.225 2024/02/06 22:47:21 rillig Exp $");
+__RCSID("$NetBSD: err.c,v 1.226 2024/03/01 19:39:28 rillig Exp $");
 #endif
 
 #include <limits.h>
@@ -412,6 +412,25 @@ static const char *const msgs[] = {
 	"'_Static_assert' requires C11 or later",			// 354
 	"'_Static_assert' without message requires C23 or later",	// 355
 	"short octal escape '%.*s' followed by digit '%c'",		// 356
+	"hex escape '%.*s' mixes uppercase and lowercase digits",	// 357
+	"hex escape '%.*s' has more than 2 digits",			// 358
+	"missing new-style '\\177' or old-style number base",		// 359
+	"missing new-style number base after '\\177'",			// 360
+	"number base '%.*s' is %ju, should be 8, 10 or 16",		// 361
+	"old-style format contains '\\0'",				// 362
+	"non-printing character '%.*s' in description '%.*s'",		// 363
+	"missing bit position after '%.*s'",				// 364
+	"missing field width after '%.*s'",				// 365
+	"missing '\\0' at the end of '%.*s'",				// 366
+	"empty description in '%.*s'",					// 367
+	"missing comparison value after directive '%.*s'",		// 368
+	"bit position '%.*s' in '%.*s' should be escaped as octal or hex", // 369
+	"field width '%.*s' in '%.*s' should be escaped as octal or hex", // 370
+	"bit position '%.*s' (%ju) in '%.*s' out of range %u..%u",	// 371
+	"field width '%.*s' (%ju) in '%.*s' out of range 0..%u",	// 372
+	"bit field end %ju in '%.*s' out of range 0..64",		// 373
+	"unknown directive '%.*s'",					// 374
+	"comparison value '%.*s' (%ju) exceeds field width %ju",	// 375
 };
 
 static bool is_suppressed[sizeof(msgs) / sizeof(msgs[0])];

Index: src/usr.bin/xlint/lint1/externs1.h
diff -u src/usr.bin/xlint/lint1/externs1.h:1.216 src/usr.bin/xlint/lint1/externs1.h:1.217
--- src/usr.bin/xlint/lint1/externs1.h:1.216	Mon Feb  5 23:11:22 2024
+++ src/usr.bin/xlint/lint1/externs1.h	Fri Mar  1 19:39:28 2024
@@ -1,4 +1,4 @@
-/*	$NetBSD: externs1.h,v 1.216 2024/02/05 23:11:22 rillig Exp $	*/
+/*	$NetBSD: externs1.h,v 1.217 2024/03/01 19:39:28 rillig Exp $	*/
 
 /*
  * Copyright (c) 1994, 1995 Jochen Pohl
@@ -419,3 +419,6 @@ void check_getopt_begin_switch(void);
 void check_getopt_case_label(int64_t);
 void check_getopt_end_switch(void);
 void check_getopt_end_while(void);
+
+/* cksnprintb.c */
+void check_snprintb(const tnode_t *);

Index: src/usr.bin/xlint/lint1/tree.c
diff -u src/usr.bin/xlint/lint1/tree.c:1.605 src/usr.bin/xlint/lint1/tree.c:1.606
--- src/usr.bin/xlint/lint1/tree.c:1.605	Thu Feb  8 20:59:19 2024
+++ src/usr.bin/xlint/lint1/tree.c	Fri Mar  1 19:39:28 2024
@@ -1,4 +1,4 @@
-/*	$NetBSD: tree.c,v 1.605 2024/02/08 20:59:19 rillig Exp $	*/
+/*	$NetBSD: tree.c,v 1.606 2024/03/01 19:39:28 rillig Exp $	*/
 
 /*
  * Copyright (c) 1994, 1995 Jochen Pohl
@@ -37,7 +37,7 @@
 
 #include <sys/cdefs.h>
 #if defined(__RCSID)
-__RCSID("$NetBSD: tree.c,v 1.605 2024/02/08 20:59:19 rillig Exp $");
+__RCSID("$NetBSD: tree.c,v 1.606 2024/03/01 19:39:28 rillig Exp $");
 #endif
 
 #include <float.h>
@@ -4444,6 +4444,7 @@ check_expr_call(const tnode_t *tn, const
 	lint_assert(ln->tn_left->tn_op == NAME);
 	if (!szof && !is_compiler_builtin(ln->tn_left->tn_sym->s_name))
 		outcall(tn, vctx || cond, retval_discarded);
+	check_snprintb(tn);
 }
 
 static void

Added files:

Index: src/tests/usr.bin/xlint/lint1/msg_357.c
diff -u /dev/null src/tests/usr.bin/xlint/lint1/msg_357.c:1.1
--- /dev/null	Fri Mar  1 19:39:29 2024
+++ src/tests/usr.bin/xlint/lint1/msg_357.c	Fri Mar  1 19:39:28 2024
@@ -0,0 +1,50 @@
+/*	$NetBSD: msg_357.c,v 1.1 2024/03/01 19:39:28 rillig Exp $	*/
+# 3 "msg_357.c"
+
+// Test for message: hex escape '%.*s' mixes uppercase and lowercase digits [357]
+
+/*
+ * In the format argument of the snprintb and snprintb_m functions, a bit
+ * position or field width is written as an octal or hexadecimal escape
+ * sequence.  If the description that follows starts with hex digits (A-Fa-f),
+ * these digits are still part of the escape sequence instead of the
+ * description.
+ *
+ * Since the escape sequences are typically written in lowercase and the
+ * descriptions are typically written in uppercase, a mixture of both cases
+ * indicates a mismatch.
+ */
+
+/* lint1-extra-flags: -X 351 */
+
+typedef typeof(sizeof(0)) size_t;
+typedef unsigned long long uint64_t;
+
+int snprintb(char*, size_t, const char*, uint64_t);
+
+void
+examples(unsigned u32, uint64_t u64)
+{
+	char buf[64];
+
+	/* expect+5: warning: hex escape '\x0aB' mixes uppercase and lowercase digits [357] */
+	/* expect+4: warning: hex escape '\x0aB' has more than 2 digits [358] */
+	/* expect+3: warning: bit position '\x0aB' (171) in '\x0aBIT' out of range 1..32 [371] */
+	snprintb(buf, sizeof(buf),
+	    "\020\x0aBIT",
+	    u32);
+
+	// This mismatch goes undetected as it has only 2 digits, does not mix
+	// case and is in bounds.  A spellchecker could mark the unknown word
+	// 'ield' to give a hint.
+	snprintb(buf, sizeof(buf),
+	    "\020\x1FIELD",
+	    u32);
+
+	/* expect+5: warning: hex escape '\x0aB' mixes uppercase and lowercase digits [357] */
+	/* expect+4: warning: hex escape '\x0aB' has more than 2 digits [358] */
+	/* expect+3: warning: bit position '\x0aB' (171) in 'b\x0aBIT\0' out of range 0..63 [371] */
+	snprintb(buf, sizeof(buf),
+	    "\177\020b\x0aBIT\0",
+	    u64);
+}
Index: src/tests/usr.bin/xlint/lint1/msg_358.c
diff -u /dev/null src/tests/usr.bin/xlint/lint1/msg_358.c:1.1
--- /dev/null	Fri Mar  1 19:39:29 2024
+++ src/tests/usr.bin/xlint/lint1/msg_358.c	Fri Mar  1 19:39:28 2024
@@ -0,0 +1,52 @@
+/*	$NetBSD: msg_358.c,v 1.1 2024/03/01 19:39:28 rillig Exp $	*/
+# 3 "msg_358.c"
+
+// Test for message: hex escape '%.*s' has more than 2 digits [358]
+
+/*
+ * In the format argument of the snprintb and snprintb_m functions, a bit
+ * position or field width is written as an octal or hexadecimal escape
+ * sequence.  If the description that follows starts with hex digits (A-Fa-f),
+ * these digits are still part of the escape sequence instead of the
+ * description.
+ */
+
+/* lint1-extra-flags: -X 351 */
+
+typedef typeof(sizeof(0)) size_t;
+typedef unsigned long long uint64_t;
+
+int snprintb(char*, size_t, const char*, uint64_t);
+
+void
+examples(unsigned u32, uint64_t u64)
+{
+	char buf[64];
+
+	/* expect+3: warning: hex escape '\x01B' has more than 2 digits [358] */
+	snprintb(buf, sizeof(buf),
+	    "\020\x01BIT",
+	    u32);
+
+	/* expect+3: warning: hex escape '\x01b' has more than 2 digits [358] */
+	snprintb(buf, sizeof(buf),
+	    "\020\x01bit",
+	    u32);
+
+	// This mismatch goes undetected as it has only 2 digits, does not mix
+	// case and is in bounds.  A spellchecker could mark the unknown word
+	// 'ield' to give a hint.
+	snprintb(buf, sizeof(buf),
+	    "\020\x1FIELD",
+	    u32);
+
+	/* expect+3: warning: hex escape '\x01b' has more than 2 digits [358] */
+	snprintb(buf, sizeof(buf),
+	    "\177\020b\x01bit\0",
+	    u64);
+
+	/* expect+3: warning: hex escape '\x02b' has more than 2 digits [358] */
+	snprintb(buf, sizeof(buf),
+	    "\177\020f\x00\x02bit\0",
+	    u64);
+}
Index: src/tests/usr.bin/xlint/lint1/msg_359.c
diff -u /dev/null src/tests/usr.bin/xlint/lint1/msg_359.c:1.1
--- /dev/null	Fri Mar  1 19:39:29 2024
+++ src/tests/usr.bin/xlint/lint1/msg_359.c	Fri Mar  1 19:39:28 2024
@@ -0,0 +1,27 @@
+/*	$NetBSD: msg_359.c,v 1.1 2024/03/01 19:39:28 rillig Exp $	*/
+# 3 "msg_359.c"
+
+// Test for message: missing new-style '\177' or old-style number base [359]
+
+/*
+ * The first or second character of the snprintb format specifies the number
+ * base.  It must be given in binary.
+ */
+
+/* lint1-extra-flags: -X 351 */
+
+typedef typeof(sizeof(0)) size_t;
+typedef unsigned long long uint64_t;
+
+int snprintb(char*, size_t, const char*, uint64_t);
+
+void
+old_style_number_base(void)
+{
+	char buf[64];
+
+	/* expect+1: warning: missing new-style '\177' or old-style number base [359] */
+	snprintb(buf, sizeof(buf), "", 0);
+	snprintb(buf, sizeof(buf), "\010", 0);
+	snprintb(buf, sizeof(buf), "" "\177\020" "", 0);
+}
Index: src/tests/usr.bin/xlint/lint1/msg_360.c
diff -u /dev/null src/tests/usr.bin/xlint/lint1/msg_360.c:1.1
--- /dev/null	Fri Mar  1 19:39:29 2024
+++ src/tests/usr.bin/xlint/lint1/msg_360.c	Fri Mar  1 19:39:28 2024
@@ -0,0 +1,28 @@
+/*	$NetBSD: msg_360.c,v 1.1 2024/03/01 19:39:28 rillig Exp $	*/
+# 3 "msg_360.c"
+
+// Test for message: missing new-style number base after '\177' [360]
+
+/*
+ * The new-style format requires the number base as the second character.
+ * This check is merely a byproduct of the implementation, it does not provide
+ * much value on its own.
+ */
+
+/* lint1-extra-flags: -X 351 */
+
+typedef typeof(sizeof(0)) size_t;
+typedef unsigned long long uint64_t;
+
+int snprintb(char*, size_t, const char*, uint64_t);
+
+void
+new_style_number_base(void)
+{
+	char buf[64];
+
+	/* expect+1: warning: missing new-style number base after '\177' [360] */
+	snprintb(buf, sizeof(buf), "\177", 0);
+	/* expect+1: warning: number base '\002' is 2, should be 8, 10 or 16 [361] */
+	snprintb(buf, sizeof(buf), "\177\002", 0);
+}
Index: src/tests/usr.bin/xlint/lint1/msg_361.c
diff -u /dev/null src/tests/usr.bin/xlint/lint1/msg_361.c:1.1
--- /dev/null	Fri Mar  1 19:39:29 2024
+++ src/tests/usr.bin/xlint/lint1/msg_361.c	Fri Mar  1 19:39:28 2024
@@ -0,0 +1,52 @@
+/*	$NetBSD: msg_361.c,v 1.1 2024/03/01 19:39:28 rillig Exp $	*/
+# 3 "msg_361.c"
+
+// Test for message: number base '%.*s' is %ju, should be 8, 10 or 16 [361]
+
+/*
+ * The first or second character of the snprintb format specifies the number
+ * base.  It must be given in binary.
+ */
+
+/* lint1-extra-flags: -X 351 */
+
+typedef typeof(sizeof(0)) size_t;
+typedef unsigned long long uint64_t;
+
+int snprintb(char*, size_t, const char*, uint64_t);
+
+void
+old_style_number_base(void)
+{
+	char buf[64];
+
+	/* expect+1: warning: missing new-style '\177' or old-style number base [359] */
+	snprintb(buf, sizeof(buf), "", 0);
+	/* expect+1: warning: number base '\002' is 2, should be 8, 10 or 16 [361] */
+	snprintb(buf, sizeof(buf), "\002", 0);
+	snprintb(buf, sizeof(buf), "\010", 0);
+	snprintb(buf, sizeof(buf), "\n", 0);
+	snprintb(buf, sizeof(buf), "\020", 0);
+	/* expect+1: warning: number base '\014' is 12, should be 8, 10 or 16 [361] */
+	snprintb(buf, sizeof(buf), "" "\014" "", 0);
+	snprintb(buf, sizeof(buf), "" "\020" "", 0);
+}
+
+void
+new_style_number_base(void)
+{
+	char buf[64];
+
+	/* expect+1: warning: missing new-style number base after '\177' [360] */
+	snprintb(buf, sizeof(buf), "\177", 0);
+	/* expect+1: warning: number base '\0' is 0, should be 8, 10 or 16 [361] */
+	snprintb(buf, sizeof(buf), "\177\0", 0);
+	/* expect+1: warning: number base '\002' is 2, should be 8, 10 or 16 [361] */
+	snprintb(buf, sizeof(buf), "\177\002", 0);
+	snprintb(buf, sizeof(buf), "\177\010", 0);
+	snprintb(buf, sizeof(buf), "\177\n", 0);
+	snprintb(buf, sizeof(buf), "\177\020", 0);
+	/* expect+1: warning: number base '\014' is 12, should be 8, 10 or 16 [361] */
+	snprintb(buf, sizeof(buf), "" "\177\014" "", 0);
+	snprintb(buf, sizeof(buf), "" "\177\020" "", 0);
+}
Index: src/tests/usr.bin/xlint/lint1/msg_362.c
diff -u /dev/null src/tests/usr.bin/xlint/lint1/msg_362.c:1.1
--- /dev/null	Fri Mar  1 19:39:29 2024
+++ src/tests/usr.bin/xlint/lint1/msg_362.c	Fri Mar  1 19:39:28 2024
@@ -0,0 +1,28 @@
+/*	$NetBSD: msg_362.c,v 1.1 2024/03/01 19:39:28 rillig Exp $	*/
+# 3 "msg_362.c"
+
+// Test for message: old-style format contains '\0' [362]
+
+/*
+ * The old-style format uses 1-based bit positions, from 1 up to 32.
+ * A null character would prematurely end the format argument.
+ */
+
+/* lint1-extra-flags: -X 351 */
+
+typedef typeof(sizeof(0)) size_t;
+typedef unsigned long long uint64_t;
+
+int snprintb(char*, size_t, const char*, uint64_t);
+
+void
+example(unsigned u32)
+{
+	char buf[64];
+
+	/* expect+1: warning: bit position '\000' (0) in '\000lsb' out of range 1..32 [371] */
+	snprintb(buf, sizeof(buf), "\020\000lsb\037msb", u32);
+	/* expect+2: warning: old-style format contains '\0' [362] */
+	/* expect+1: warning: bit position '\000' (0) in '\000lsb' out of range 1..32 [371] */
+	snprintb(buf, sizeof(buf), "\020\037msb\000lsb", u32);
+}
Index: src/tests/usr.bin/xlint/lint1/msg_363.c
diff -u /dev/null src/tests/usr.bin/xlint/lint1/msg_363.c:1.1
--- /dev/null	Fri Mar  1 19:39:29 2024
+++ src/tests/usr.bin/xlint/lint1/msg_363.c	Fri Mar  1 19:39:28 2024
@@ -0,0 +1,41 @@
+/*	$NetBSD: msg_363.c,v 1.1 2024/03/01 19:39:28 rillig Exp $	*/
+# 3 "msg_363.c"
+
+// Test for message: non-printing character '%.*s' in description '%.*s' [363]
+
+/*
+ * The purpose of snprintb is to produce a printable, visible representation
+ * of a binary number, therefore the description should consist of visible
+ * characters only.
+ */
+
+/* lint1-extra-flags: -X 351 */
+
+typedef typeof(sizeof(0)) size_t;
+typedef unsigned long long uint64_t;
+
+int snprintb(char*, size_t, const char*, uint64_t);
+
+void
+old_style_description(unsigned u32)
+{
+	char buf[64];
+
+	/* expect+6: warning: bit position '\t' in '\tprint' should be escaped as octal or hex [369] */
+	/* expect+5: warning: non-printing character '\377' in description 'able\377' [363] */
+	/* expect+4: warning: bit position '\n' in '\nable\377' should be escaped as octal or hex [369] */
+	snprintb(buf, sizeof(buf),
+	    "\020"
+	    "\001non\tprint\nable\377",
+	    u32);
+
+	/* expect+8: warning: old-style format contains '\0' [362] */
+	/* expect+7: warning: bit position '\000' (0) in '\000print' out of range 1..32 [371] */
+	/* expect+6: warning: old-style format contains '\0' [362] */
+	/* expect+5: warning: bit position '\n' in '\nable' should be escaped as octal or hex [369] */
+	/* expect+4: warning: empty description in '\0' [367] */
+	snprintb(buf, sizeof(buf),
+	    "\020"
+	    "\001non\000print\nable\0",
+	    u32);
+}
Index: src/tests/usr.bin/xlint/lint1/msg_364.c
diff -u /dev/null src/tests/usr.bin/xlint/lint1/msg_364.c:1.1
--- /dev/null	Fri Mar  1 19:39:29 2024
+++ src/tests/usr.bin/xlint/lint1/msg_364.c	Fri Mar  1 19:39:28 2024
@@ -0,0 +1,34 @@
+/*	$NetBSD: msg_364.c,v 1.1 2024/03/01 19:39:28 rillig Exp $	*/
+# 3 "msg_364.c"
+
+// Test for message: missing bit position after '%.*s' [364]
+
+/*
+ * The directives 'b', 'f' and 'F' require a bit position as their first
+ * argument.
+ */
+
+/* lint1-extra-flags: -X 351 */
+
+typedef typeof(sizeof(0)) size_t;
+typedef unsigned long long uint64_t;
+
+int snprintb(char*, size_t, const char*, uint64_t);
+
+void
+example(unsigned u32)
+{
+	char buf[64];
+
+	/* expect+4: warning: missing bit position after 'b' [364] */
+	snprintb(buf, sizeof(buf),
+	    "\177\020"
+	    "b",
+	    u32);
+
+	/* expect+4: warning: missing '\0' at the end of 'b\007' [366] */
+	snprintb(buf, sizeof(buf),
+	    "\177\020"
+	    "b\007",
+	    u32);
+}
Index: src/tests/usr.bin/xlint/lint1/msg_365.c
diff -u /dev/null src/tests/usr.bin/xlint/lint1/msg_365.c:1.1
--- /dev/null	Fri Mar  1 19:39:29 2024
+++ src/tests/usr.bin/xlint/lint1/msg_365.c	Fri Mar  1 19:39:28 2024
@@ -0,0 +1,33 @@
+/*	$NetBSD: msg_365.c,v 1.1 2024/03/01 19:39:28 rillig Exp $	*/
+# 3 "msg_365.c"
+
+// Test for message: missing field width after '%.*s' [365]
+
+/*
+ * The directives 'f' and 'F' require a field width as their second argument.
+ */
+
+/* lint1-extra-flags: -X 351 */
+
+typedef typeof(sizeof(0)) size_t;
+typedef unsigned long long uint64_t;
+
+int snprintb(char*, size_t, const char*, uint64_t);
+
+void
+example(unsigned u32)
+{
+	char buf[64];
+
+	/* expect+4: warning: missing field width after 'f\000' [365] */
+	snprintb(buf, sizeof(buf),
+	    "\177\020"
+	    "f\000",
+	    u32);
+
+	/* expect+4: warning: missing '\0' at the end of 'f\007\010' [366] */
+	snprintb(buf, sizeof(buf),
+	    "\177\020"
+	    "f\007\010",
+	    u32);
+}
Index: src/tests/usr.bin/xlint/lint1/msg_366.c
diff -u /dev/null src/tests/usr.bin/xlint/lint1/msg_366.c:1.1
--- /dev/null	Fri Mar  1 19:39:29 2024
+++ src/tests/usr.bin/xlint/lint1/msg_366.c	Fri Mar  1 19:39:28 2024
@@ -0,0 +1,68 @@
+/*	$NetBSD: msg_366.c,v 1.1 2024/03/01 19:39:28 rillig Exp $	*/
+# 3 "msg_366.c"
+
+// Test for message: missing '\0' at the end of '%.*s' [366]
+
+/*
+ * In the new-style format, each directive ends with a '\0'.  If that's not
+ * the case, snprintb will read beyond the end of the format argument, looking
+ * for the terminating '\0'.  In the most common case where the format comes
+ * from a string literal, the '\0' from the directive needs to be spelled out,
+ * while the '\0' that terminates the sequence of directives is provided by
+ * the C compiler.
+ */
+
+/* lint1-extra-flags: -X 351 */
+
+typedef typeof(sizeof(0)) size_t;
+typedef unsigned long long uint64_t;
+
+int snprintb(char*, size_t, const char*, uint64_t);
+
+void
+example(unsigned u32)
+{
+	char buf[64];
+
+	/* expect+4: warning: unknown directive '\0' [374] */
+	snprintb(buf, sizeof(buf),
+	    "\177\020"
+	    "\0",
+	    u32);
+
+	/* expect+4: warning: missing '\0' at the end of 'b\007' [366] */
+	snprintb(buf, sizeof(buf),
+	    "\177\020"
+	    "b\007",
+	    u32);
+
+	/* expect+4: warning: missing '\0' at the end of 'f\007\000' [366] */
+	snprintb(buf, sizeof(buf),
+	    "\177\020"
+	    "f\007\000",
+	    u32);
+
+	/* expect+4: warning: missing '\0' at the end of 'F\007\000' [366] */
+	snprintb(buf, sizeof(buf),
+	    "\177\020"
+	    "F\007\000",
+	    u32);
+
+	/* expect+4: warning: missing '\0' at the end of '=\007value' [366] */
+	snprintb(buf, sizeof(buf),
+	    "\177\020"
+	    "=\007value",
+	    u32);
+
+	/* expect+4: warning: missing '\0' at the end of ':\007value' [366] */
+	snprintb(buf, sizeof(buf),
+	    "\177\020"
+	    ":\007value",
+	    u32);
+
+	/* expect+4: warning: missing '\0' at the end of '*default' [366] */
+	snprintb(buf, sizeof(buf),
+	    "\177\020"
+	    "*default",
+	    u32);
+}
Index: src/tests/usr.bin/xlint/lint1/msg_367.c
diff -u /dev/null src/tests/usr.bin/xlint/lint1/msg_367.c:1.1
--- /dev/null	Fri Mar  1 19:39:29 2024
+++ src/tests/usr.bin/xlint/lint1/msg_367.c	Fri Mar  1 19:39:28 2024
@@ -0,0 +1,62 @@
+/*	$NetBSD: msg_367.c,v 1.1 2024/03/01 19:39:28 rillig Exp $	*/
+# 3 "msg_367.c"
+
+// Test for message: empty description in '%.*s' [367]
+
+/*
+ * Each bit or field or comparison value gets a description.  If such a
+ * description is empty, the generated output will contain empty angle
+ * brackets or multiple adjacent commas or commas adjacent to an angle
+ * bracket, such as '<,,,,>'.
+ */
+
+/* lint1-extra-flags: -X 351 */
+
+typedef typeof(sizeof(0)) size_t;
+typedef unsigned long long uint64_t;
+
+int snprintb(char*, size_t, const char*, uint64_t);
+
+void
+example(unsigned u32)
+{
+	char buf[64];
+
+	/* expect+4: warning: empty description in 'b\000\0' [367] */
+	snprintb(buf, sizeof(buf),
+	    "\177\020"
+	    "b\000\0",
+	    u32);
+
+	/* expect+4: warning: empty description in 'f\000\010\0' [367] */
+	snprintb(buf, sizeof(buf),
+	    "\177\020"
+	    "f\000\010\0",
+	    u32);
+
+	// No warning, as 'F' does not take a description.
+	// If there were a description, it would simply be skipped.
+	snprintb(buf, sizeof(buf),
+	    "\177\020"
+	    "F\000\010\0",
+	    u32);
+
+	/* expect+4: warning: empty description in '=\000\0' [367] */
+	snprintb(buf, sizeof(buf),
+	    "\177\020"
+	    "=\000\0",
+	    u32);
+
+	/* expect+4: warning: empty description in ':\000\0' [367] */
+	snprintb(buf, sizeof(buf),
+	    "\177\020"
+	    ":\000\0",
+	    u32);
+
+	/* expect+4: warning: empty description in '*\0' [367] */
+	snprintb(buf, sizeof(buf),
+	    "\177\020"
+	    "*\0",
+	    u32);
+
+}
Index: src/tests/usr.bin/xlint/lint1/msg_368.c
diff -u /dev/null src/tests/usr.bin/xlint/lint1/msg_368.c:1.1
--- /dev/null	Fri Mar  1 19:39:29 2024
+++ src/tests/usr.bin/xlint/lint1/msg_368.c	Fri Mar  1 19:39:29 2024
@@ -0,0 +1,34 @@
+/*	$NetBSD: msg_368.c,v 1.1 2024/03/01 19:39:29 rillig Exp $	*/
+# 3 "msg_368.c"
+
+// Test for message: missing comparison value after directive '%.*s' [368]
+
+/*
+ * The directives '=' and ':' require a comparison value as their argument,
+ * followed by the description and the terminating null character.
+ */
+
+/* lint1-extra-flags: -X 351 */
+
+typedef typeof(sizeof(0)) size_t;
+typedef unsigned long long uint64_t;
+
+int snprintb(char*, size_t, const char*, uint64_t);
+
+void
+example(uint64_t val)
+{
+	char buf[64];
+
+	/* expect+4: warning: missing comparison value after directive '=' [368] */
+	snprintb(buf, sizeof(buf),
+	    "\177\020"
+	    "=",
+	    val);
+
+	/* expect+4: warning: missing comparison value after directive ':' [368] */
+	snprintb(buf, sizeof(buf),
+	    "\177\020"
+	    ":",
+	    val);
+}
Index: src/tests/usr.bin/xlint/lint1/msg_369.c
diff -u /dev/null src/tests/usr.bin/xlint/lint1/msg_369.c:1.1
--- /dev/null	Fri Mar  1 19:39:29 2024
+++ src/tests/usr.bin/xlint/lint1/msg_369.c	Fri Mar  1 19:39:29 2024
@@ -0,0 +1,52 @@
+/*	$NetBSD: msg_369.c,v 1.1 2024/03/01 19:39:29 rillig Exp $	*/
+# 3 "msg_369.c"
+
+// Test for message: bit position '%.*s' in '%.*s' should be escaped as octal or hex [369]
+
+/*
+ * To distinguish bit positions from the description text, they should use
+ * octal or hex escape sequences.  Of these, octal escape sequences are less
+ * error-prone, as they consist of at most 3 octal digits, whereas hex escape
+ * sequences consume as many digits as available.
+ */
+
+/* lint1-extra-flags: -X 351 */
+
+typedef typeof(sizeof(0)) size_t;
+typedef unsigned long long uint64_t;
+
+int snprintb(char*, size_t, const char*, uint64_t);
+
+void
+example(unsigned u32, uint64_t u64)
+{
+	char buf[64];
+
+	/* expect+8: warning: bit position ' ' in ' space' should be escaped as octal or hex [369] */
+	/* expect+7: warning: bit position '\t' in '\ttab' should be escaped as octal or hex [369] */
+	/* expect+6: warning: bit position '\n' in '\nnewline' should be escaped as octal or hex [369] */
+	snprintb(buf, sizeof(buf),
+	    "\020"
+	    " space"
+	    "\ttab"
+	    "\nnewline",
+	    u32);
+
+	/* expect+8: warning: bit position ' ' in 'b space\0' should be escaped as octal or hex [369] */
+	/* expect+7: warning: bit position '\t' in 'b\ttab\0' should be escaped as octal or hex [369] */
+	/* expect+6: warning: bit position '\n' in 'b\nnewline\0' should be escaped as octal or hex [369] */
+	snprintb(buf, sizeof(buf),
+	    "\177\020"
+	    "b space\0"
+	    "b\ttab\0"
+	    "b\nnewline\0",
+	    u64);
+
+	/* expect+6: warning: bit position '\t' in 'f\t\010tab\0' should be escaped as octal or hex [369] */
+	/* expect+5: warning: bit position '\n' in 'F\n\010newline\0' should be escaped as octal or hex [369] */
+	snprintb(buf, sizeof(buf),
+	    "\177\020"
+	    "f\t\010tab\0"
+	    "F\n\010newline\0",
+	    u64);
+}
Index: src/tests/usr.bin/xlint/lint1/msg_370.c
diff -u /dev/null src/tests/usr.bin/xlint/lint1/msg_370.c:1.1
--- /dev/null	Fri Mar  1 19:39:29 2024
+++ src/tests/usr.bin/xlint/lint1/msg_370.c	Fri Mar  1 19:39:29 2024
@@ -0,0 +1,50 @@
+/*	$NetBSD: msg_370.c,v 1.1 2024/03/01 19:39:29 rillig Exp $	*/
+# 3 "msg_370.c"
+
+// Test for message: field width '%.*s' in '%.*s' should be escaped as octal or hex [370]
+
+/*
+ * To distinguish field widths from the description text, they should use
+ * octal or hex escape sequences.  Of these, octal escape sequences are less
+ * error-prone, as they consist of at most 3 octal digits, whereas hex escape
+ * sequences consume as many digits as available.
+ */
+
+/* lint1-extra-flags: -X 351 */
+
+typedef typeof(sizeof(0)) size_t;
+typedef unsigned long long uint64_t;
+
+int snprintb(char*, size_t, const char*, uint64_t);
+
+void
+example(uint64_t u64)
+{
+	char buf[64];
+
+	/* expect+11: warning: bit position ' ' in 'f  space\0' should be escaped as octal or hex [369] */
+	/* expect+10: warning: field width ' ' in 'f  space\0' should be escaped as octal or hex [370] */
+	/* expect+9: warning: bit position '\t' in 'f\t\ttab\0' should be escaped as octal or hex [369] */
+	/* expect+8: warning: field width '\t' in 'f\t\ttab\0' should be escaped as octal or hex [370] */
+	/* expect+7: warning: bit position '\n' in 'f\n\nnewline\0' should be escaped as octal or hex [369] */
+	/* expect+6: warning: field width '\n' in 'f\n\nnewline\0' should be escaped as octal or hex [370] */
+	snprintb(buf, sizeof(buf),
+	    "\177\020"
+	    "f  space\0"
+	    "f\t\ttab\0"
+	    "f\n\nnewline\0",
+	    u64);
+
+	/* expect+11: warning: bit position ' ' in 'F  space\0' should be escaped as octal or hex [369] */
+	/* expect+10: warning: field width ' ' in 'F  space\0' should be escaped as octal or hex [370] */
+	/* expect+9: warning: bit position '\t' in 'F\t\ttab\0' should be escaped as octal or hex [369] */
+	/* expect+8: warning: field width '\t' in 'F\t\ttab\0' should be escaped as octal or hex [370] */
+	/* expect+7: warning: bit position '\n' in 'F\n\nnewline\0' should be escaped as octal or hex [369] */
+	/* expect+6: warning: field width '\n' in 'F\n\nnewline\0' should be escaped as octal or hex [370] */
+	snprintb(buf, sizeof(buf),
+	    "\177\020"
+	    "F  space\0"
+	    "F\t\ttab\0"
+	    "F\n\nnewline\0",
+	    u64);
+}
Index: src/tests/usr.bin/xlint/lint1/msg_371.c
diff -u /dev/null src/tests/usr.bin/xlint/lint1/msg_371.c:1.1
--- /dev/null	Fri Mar  1 19:39:29 2024
+++ src/tests/usr.bin/xlint/lint1/msg_371.c	Fri Mar  1 19:39:29 2024
@@ -0,0 +1,61 @@
+/*	$NetBSD: msg_371.c,v 1.1 2024/03/01 19:39:29 rillig Exp $	*/
+# 3 "msg_371.c"
+
+// Test for message: bit position '%.*s' (%ju) in '%.*s' out of range %u..%u [371]
+
+/*
+ * In old-style formats, bit positions are 1-based and must be in the range
+ * from 1 to 32.  In new-style formats, bit positions are 0-based and must be
+ * in the range from 0 to 63.
+ */
+
+/* lint1-extra-flags: -X 351 */
+
+typedef typeof(sizeof(0)) size_t;
+typedef unsigned long long uint64_t;
+
+int snprintb(char*, size_t, const char*, uint64_t);
+
+void
+example(unsigned u32, uint64_t u64)
+{
+	char buf[64];
+
+	/* expect+11: warning: bit position '\000' (0) in '\000zero' out of range 1..32 [371] */
+	/* expect+10: warning: non-printing character '\177' in description 'bit32""\041bit33""\177' [363] */
+	/* expect+9: warning: non-printing character '\377' in description 'bit32""\041bit33""\177bit127""\377' [363] */
+	snprintb(buf, sizeof(buf),
+	    "\020"
+	    "\000zero"
+	    "\001bit1"
+	    "\040bit32"
+	    "\041bit33"
+	    "\177bit127"
+	    "\377bit255",
+	    u32);
+
+	/* expect+10: warning: bit position '\100' (64) in 'b\100bit64\0' out of range 0..63 [371] */
+	/* expect+9: warning: bit position '\177' (127) in 'b\177bit127\0' out of range 0..63 [371] */
+	/* expect+8: warning: bit position '\377' (255) in 'b\377bit255\0' out of range 0..63 [371] */
+	snprintb(buf, sizeof(buf),
+	    "\177\020"
+	    "b\000bit0\0"
+	    "b\077bit63\0"
+	    "b\100bit64\0"
+	    "b\177bit127\0"
+	    "b\377bit255\0",
+	    u64);
+
+	/* expect+11: warning: bit position '\100' (64) in 'F\100\000none\0' out of range 0..63 [371] */
+	/* expect+10: warning: bit position '\100' (64) in 'f\100\001oob\0' out of range 0..63 [371] */
+	/* expect+9: warning: bit field end 65 in 'f\100\001oob\0' out of range 0..64 [373] */
+	/* expect+8: warning: bit position '\101' (65) in 'F\101\001oob\0' out of range 0..63 [371] */
+	/* expect+7: warning: bit field end 66 in 'F\101\001oob\0' out of range 0..64 [373] */
+	snprintb(buf, sizeof(buf),
+	    "\177\020"
+	    "f\077\001msb\0"
+	    "F\100\000none\0"
+	    "f\100\001oob\0"
+	    "F\101\001oob\0",
+	    u64);
+}
Index: src/tests/usr.bin/xlint/lint1/msg_372.c
diff -u /dev/null src/tests/usr.bin/xlint/lint1/msg_372.c:1.1
--- /dev/null	Fri Mar  1 19:39:29 2024
+++ src/tests/usr.bin/xlint/lint1/msg_372.c	Fri Mar  1 19:39:29 2024
@@ -0,0 +1,35 @@
+/*	$NetBSD: msg_372.c,v 1.1 2024/03/01 19:39:29 rillig Exp $	*/
+# 3 "msg_372.c"
+
+// Test for message: field width '%.*s' (%ju) in '%.*s' out of range 0..%u [372]
+
+/*
+ * In new-style formats, the width of a bit-field must be between 0 (an empty
+ * bit-field) and 64 (a bit-field spanning the whole value).
+ */
+
+/* lint1-extra-flags: -X 351 */
+
+typedef typeof(sizeof(0)) size_t;
+typedef unsigned long long uint64_t;
+
+int snprintb(char*, size_t, const char*, uint64_t);
+
+void
+example(uint64_t u64)
+{
+	char buf[64];
+
+	/* expect+11: warning: field width '\101' (65) in 'f\000\101all+1\0' out of range 0..64 [372] */
+	/* expect+10: warning: bit field end 65 in 'f\000\101all+1\0' out of range 0..64 [373] */
+	/* expect+9: warning: bit field end 65 in 'f\001\100oob64\0' out of range 0..64 [373] */
+	/* expect+8: warning: field width '\377' (255) in 'f\010\377oob64\0' out of range 0..64 [372] */
+	/* expect+7: warning: bit field end 263 in 'f\010\377oob64\0' out of range 0..64 [373] */
+	snprintb(buf, sizeof(buf),
+	    "\177\020"
+	    "f\000\100all\0"
+	    "f\000\101all+1\0"
+	    "f\001\100oob64\0"
+	    "f\010\377oob64\0",
+	    u64);
+}
Index: src/tests/usr.bin/xlint/lint1/msg_373.c
diff -u /dev/null src/tests/usr.bin/xlint/lint1/msg_373.c:1.1
--- /dev/null	Fri Mar  1 19:39:29 2024
+++ src/tests/usr.bin/xlint/lint1/msg_373.c	Fri Mar  1 19:39:29 2024
@@ -0,0 +1,36 @@
+/*	$NetBSD: msg_373.c,v 1.1 2024/03/01 19:39:29 rillig Exp $	*/
+# 3 "msg_373.c"
+
+// Test for message: bit field end %ju in '%.*s' out of range 0..64 [373]
+
+/*
+ * A bit-field may start in the middle of the value.  When its end goes beyond
+ * 64, this means the uppermost bits will always be 0, and a narrower
+ * bit-field would have the same effect.
+ */
+
+/* lint1-extra-flags: -X 351 */
+
+typedef typeof(sizeof(0)) size_t;
+typedef unsigned long long uint64_t;
+
+int snprintb(char*, size_t, const char*, uint64_t);
+
+void
+example(uint64_t u64)
+{
+	char buf[64];
+
+	/* expect+11: warning: field width '\101' (65) in 'f\000\101all+1\0' out of range 0..64 [372] */
+	/* expect+10: warning: bit field end 65 in 'f\000\101all+1\0' out of range 0..64 [373] */
+	/* expect+9: warning: bit field end 65 in 'f\001\100oob64\0' out of range 0..64 [373] */
+	/* expect+8: warning: field width '\377' (255) in 'f\010\377oob64\0' out of range 0..64 [372] */
+	/* expect+7: warning: bit field end 263 in 'f\010\377oob64\0' out of range 0..64 [373] */
+	snprintb(buf, sizeof(buf),
+	    "\177\020"
+	    "f\000\100all\0"
+	    "f\000\101all+1\0"
+	    "f\001\100oob64\0"
+	    "f\010\377oob64\0",
+	    u64);
+}
Index: src/tests/usr.bin/xlint/lint1/msg_374.c
diff -u /dev/null src/tests/usr.bin/xlint/lint1/msg_374.c:1.1
--- /dev/null	Fri Mar  1 19:39:29 2024
+++ src/tests/usr.bin/xlint/lint1/msg_374.c	Fri Mar  1 19:39:29 2024
@@ -0,0 +1,34 @@
+/*	$NetBSD: msg_374.c,v 1.1 2024/03/01 19:39:29 rillig Exp $	*/
+# 3 "msg_374.c"
+
+// Test for message: unknown directive '%.*s' [374]
+
+/*
+ * In the new-style format, an unknown directive is assumed to have a single
+ * argument, followed by a null-terminated description.
+ */
+
+/* lint1-extra-flags: -X 351 */
+
+typedef typeof(sizeof(0)) size_t;
+typedef unsigned long long uint64_t;
+
+int snprintb(char*, size_t, const char*, uint64_t);
+
+void
+example(uint64_t u64)
+{
+	char buf[64];
+
+	/* expect+4: warning: unknown directive 'x' [374] */
+	snprintb(buf, sizeof(buf),
+	    "\177\020"
+	    "x12345\0",
+	    u64);
+
+	/* expect+4: warning: unknown directive '\000' [374] */
+	snprintb(buf, sizeof(buf),
+	    "\177\020"
+	    "\00012345\0",
+	    u64);
+}
Index: src/tests/usr.bin/xlint/lint1/msg_375.c
diff -u /dev/null src/tests/usr.bin/xlint/lint1/msg_375.c:1.1
--- /dev/null	Fri Mar  1 19:39:29 2024
+++ src/tests/usr.bin/xlint/lint1/msg_375.c	Fri Mar  1 19:39:29 2024
@@ -0,0 +1,38 @@
+/*	$NetBSD: msg_375.c,v 1.1 2024/03/01 19:39:29 rillig Exp $	*/
+# 3 "msg_375.c"
+
+// Test for message: comparison value '%.*s' (%ju) exceeds field width %ju [375]
+
+/*
+ * When a bit field can take the values 0 to 15, there is no point comparing
+ * it to 16.
+ */
+
+/* lint1-extra-flags: -X 351 */
+
+typedef typeof(sizeof(0)) size_t;
+typedef unsigned long long uint64_t;
+
+int snprintb(char*, size_t, const char*, uint64_t);
+
+void
+example(uint64_t u64)
+{
+	char buf[64];
+
+	/* expect+14: warning: comparison value '\020' (16) exceeds field width 4 [375] */
+	/* expect+13: warning: comparison value '\377' (255) exceeds field width 4 [375] */
+	/* expect+12: warning: comparison value '\020' (16) exceeds field width 4 [375] */
+	/* expect+11: warning: comparison value '\377' (255) exceeds field width 4 [375] */
+	snprintb(buf, sizeof(buf),
+	    "\177\020"
+	    "f\000\004low\0"
+		"=\01715\0"
+		"=\02016\0"
+		"=\37716\0"
+	    "F\000\004low\0"
+		":\01715\0"
+		":\02016\0"
+		":\37716\0",
+	    u64);
+}

Reply via email to