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); +}