Module Name: src
Committed By: rillig
Date: Fri Aug 19 19:40:39 UTC 2022
Modified Files:
src/tests/usr.bin/xlint/lint1: msg_267.c op_shl_lp64.c
src/usr.bin/xlint/lint1: err.c tree.c
Log Message:
lint: add more details to message about large bit-shifts
To generate a diff of this commit:
cvs rdiff -u -r1.5 -r1.6 src/tests/usr.bin/xlint/lint1/msg_267.c
cvs rdiff -u -r1.3 -r1.4 src/tests/usr.bin/xlint/lint1/op_shl_lp64.c
cvs rdiff -u -r1.182 -r1.183 src/usr.bin/xlint/lint1/err.c
cvs rdiff -u -r1.475 -r1.476 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_267.c
diff -u src/tests/usr.bin/xlint/lint1/msg_267.c:1.5 src/tests/usr.bin/xlint/lint1/msg_267.c:1.6
--- src/tests/usr.bin/xlint/lint1/msg_267.c:1.5 Fri Aug 19 19:13:04 2022
+++ src/tests/usr.bin/xlint/lint1/msg_267.c Fri Aug 19 19:40:39 2022
@@ -1,19 +1,19 @@
-/* $NetBSD: msg_267.c,v 1.5 2022/08/19 19:13:04 rillig Exp $ */
+/* $NetBSD: msg_267.c,v 1.6 2022/08/19 19:40:39 rillig Exp $ */
# 3 "msg_267.c"
-// Test for message: shift equal to size of object [267]
+// Test for message: shift amount %u equals bit-size of '%s' [267]
int
shr32(unsigned int x)
{
- /* expect+1: warning: shift equal to size of object [267] */
+ /* expect+1: warning: shift amount 32 equals bit-size of 'unsigned int' [267] */
return x >> 32;
}
int
shl32(unsigned int x)
{
- /* expect+1: warning: shift equal to size of object [267] */
+ /* expect+1: warning: shift amount 32 equals bit-size of 'unsigned int' [267] */
return x << 32;
}
@@ -26,7 +26,50 @@ shl32(unsigned int x)
unsigned
function(unsigned __attribute__((mode(TI))) arg)
{
- /* XXX: The 'size' usually means the size in bytes, not in bits. */
- /* expect+1: warning: shift equal to size of object [267] */
+ /* expect+1: warning: shift amount 32 equals bit-size of 'unsigned int' [267] */
return (arg >> 32) & 3;
}
+
+unsigned
+shift_bit_field(void)
+{
+ struct {
+ unsigned bit_field:18;
+ } s = { 12345 };
+
+ /*
+ * A warning may be useful here for '>>' with a shift amount >= 18.
+ *
+ * For '<<' and bit-size <= 31, a warning only makes sense for shift
+ * amounts >= 31, as it is legitimate to rely on the default integer
+ * promotions of the left-hand operand. The default integer promotion
+ * turns the type into 'int', not 'unsigned int', therefore the 31.
+ * Using the same warning text would be confusing though.
+ *
+ * For '<<' and bit-size == 32, the standard case applies.
+ *
+ * As of 2022-08-19, Clang-tidy doesn't warn about any of these.
+ */
+ return
+ (s.bit_field >> 17) &
+ (s.bit_field >> 18) &
+ (s.bit_field >> 19) &
+ (s.bit_field >> 31) &
+ /* XXX: Why 'int:18', not 'unsigned int:18'? */
+ /* expect+1: warning: shift amount 32 equals bit-size of 'int:18' [267] */
+ (s.bit_field >> 32) &
+ /* XXX: Why 'int', not 'unsigned int:18'? */
+ /* expect+1: warning: shift amount 33 is greater than bit-size 32 of 'int' [122] */
+ (s.bit_field >> 33) &
+ (s.bit_field << 17) &
+ (s.bit_field << 18) &
+ (s.bit_field << 19) &
+ (s.bit_field << 31) &
+ /* XXX: Why 'int:18', not 'unsigned int:18'? */
+ /* expect+1: warning: shift amount 32 equals bit-size of 'int:18' [267] */
+ (s.bit_field << 32) &
+ /* XXX: Why 'int', not 'unsigned int:18'? */
+ /* expect+1: warning: shift amount 33 is greater than bit-size 32 of 'int' [122] */
+ (s.bit_field << 33) &
+ 15;
+}
Index: src/tests/usr.bin/xlint/lint1/op_shl_lp64.c
diff -u src/tests/usr.bin/xlint/lint1/op_shl_lp64.c:1.3 src/tests/usr.bin/xlint/lint1/op_shl_lp64.c:1.4
--- src/tests/usr.bin/xlint/lint1/op_shl_lp64.c:1.3 Sat Aug 21 11:50:57 2021
+++ src/tests/usr.bin/xlint/lint1/op_shl_lp64.c Fri Aug 19 19:40:39 2022
@@ -1,4 +1,4 @@
-/* $NetBSD: op_shl_lp64.c,v 1.3 2021/08/21 11:50:57 rillig Exp $ */
+/* $NetBSD: op_shl_lp64.c,v 1.4 2022/08/19 19:40:39 rillig Exp $ */
# 3 "op_shl_lp64.c"
/*
@@ -19,7 +19,7 @@ const __uint128_t zero105 =
- (((__uint128_t)1) << 9);
const __uint128_t shl_128_129 =
- /* expect+1: warning: shift equal to size of object [267] */
+ /* expect+1: warning: shift amount 128 equals bit-size of '__uint128_t' [267] */
(((__uint128_t)1) << 128)
/* expect+1: warning: shift amount 129 is greater than bit-size 128 of '__uint128_t' [122] */
- (((__uint128_t)1) << 129);
Index: src/usr.bin/xlint/lint1/err.c
diff -u src/usr.bin/xlint/lint1/err.c:1.182 src/usr.bin/xlint/lint1/err.c:1.183
--- src/usr.bin/xlint/lint1/err.c:1.182 Sat Jul 16 22:36:06 2022
+++ src/usr.bin/xlint/lint1/err.c Fri Aug 19 19:40:39 2022
@@ -1,4 +1,4 @@
-/* $NetBSD: err.c,v 1.182 2022/07/16 22:36:06 rillig Exp $ */
+/* $NetBSD: err.c,v 1.183 2022/08/19 19:40:39 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.182 2022/07/16 22:36:06 rillig Exp $");
+__RCSID("$NetBSD: err.c,v 1.183 2022/08/19 19:40:39 rillig Exp $");
#endif
#include <limits.h>
@@ -322,7 +322,7 @@ static const char *const msgs[] = {
"\\v undefined in traditional C", /* 264 */
"%s does not support 'long long'", /* 265 */
"'long double' is illegal in traditional C", /* 266 */
- "shift equal to size of object", /* 267 */
+ "shift amount %u equals bit-size of '%s'", /* 267 */
"variable '%s' declared inline", /* 268 */
"argument '%s' declared inline", /* 269 */
"function prototypes are illegal in traditional C", /* 270 */
Index: src/usr.bin/xlint/lint1/tree.c
diff -u src/usr.bin/xlint/lint1/tree.c:1.475 src/usr.bin/xlint/lint1/tree.c:1.476
--- src/usr.bin/xlint/lint1/tree.c:1.475 Sat Jul 16 22:36:06 2022
+++ src/usr.bin/xlint/lint1/tree.c Fri Aug 19 19:40:39 2022
@@ -1,4 +1,4 @@
-/* $NetBSD: tree.c,v 1.475 2022/07/16 22:36:06 rillig Exp $ */
+/* $NetBSD: tree.c,v 1.476 2022/08/19 19:40:39 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.475 2022/07/16 22:36:06 rillig Exp $");
+__RCSID("$NetBSD: tree.c,v 1.476 2022/08/19 19:40:39 rillig Exp $");
#endif
#include <float.h>
@@ -1224,7 +1224,7 @@ typeok_shl(const mod_t *mp, tspec_t lt,
}
static void
-typeok_shift(tspec_t lt, const tnode_t *rn, tspec_t rt)
+typeok_shift(const type_t *ltp, tspec_t lt, const tnode_t *rn, tspec_t rt)
{
if (rn->tn_op != CON)
return;
@@ -1234,8 +1234,8 @@ typeok_shift(tspec_t lt, const tnode_t *
warning(121);
} else if ((uint64_t)rn->tn_val->v_quad ==
(uint64_t)size_in_bits(lt)) {
- /* shift equal to size of object */
- warning(267);
+ /* shift amount %u equals bit-size of '%s' */
+ warning(267, (unsigned)rn->tn_val->v_quad, type_name(ltp));
} else if ((uint64_t)rn->tn_val->v_quad > (uint64_t)size_in_bits(lt)) {
/* shift amount %llu is greater than bit-size %llu of '%s' */
warning(122, (unsigned long long)rn->tn_val->v_quad,
@@ -1457,7 +1457,7 @@ typeok_op(op_t op, const mod_t *mp, int
case SHR:
typeok_shr(mp, ln, lt, rn, rt);
shift:
- typeok_shift(lt, rn, rt);
+ typeok_shift(ltp, lt, rn, rt);
break;
case LT:
case LE: