lint: add more details to message about large bit-shifts

This commit is contained in:
rillig 2022-08-19 19:40:39 +00:00
parent a45115be53
commit e8f3e4bdea
4 changed files with 60 additions and 17 deletions

View File

@ -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;
}

View File

@ -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);

View File

@ -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 */

View File

@ -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, tspec_t rt)
}
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 *rn, tspec_t rt)
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 arg,
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: