Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/usr.bin/xlint/lint1 lint: fix query for redundant cast befor...
details: https://anonhg.NetBSD.org/src/rev/57929c3ed368
branches: trunk
changeset: 368386:57929c3ed368
user: rillig <rillig%NetBSD.org@localhost>
date: Fri Jul 08 20:27:36 2022 +0000
description:
lint: fix query for redundant cast before assignment
Previously, 'i = (int)dbl' was marked as redundant, even though it
performs a value conversion.
diffstat:
tests/usr.bin/xlint/lint1/queries.c | 131 ++++++++++++++++++++++++++++++++---
usr.bin/xlint/lint1/README.md | 21 +++--
usr.bin/xlint/lint1/tree.c | 65 ++++++++++++++---
3 files changed, 182 insertions(+), 35 deletions(-)
diffs (truncated from 325 to 300 lines):
diff -r 315c7497dab3 -r 57929c3ed368 tests/usr.bin/xlint/lint1/queries.c
--- a/tests/usr.bin/xlint/lint1/queries.c Fri Jul 08 17:47:47 2022 +0000
+++ b/tests/usr.bin/xlint/lint1/queries.c Fri Jul 08 20:27:36 2022 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: queries.c,v 1.1 2022/07/05 22:50:41 rillig Exp $ */
+/* $NetBSD: queries.c,v 1.2 2022/07/08 20:27:36 rillig Exp $ */
# 3 "queries.c"
/*
@@ -17,6 +17,50 @@
/* lint1-extra-flags: -q 1,2,3,4,5,6,7 */
+typedef unsigned char u8_t;
+typedef unsigned short u16_t;
+typedef unsigned int u32_t;
+typedef unsigned long long u64_t;
+typedef signed char s8_t;
+typedef signed short s16_t;
+typedef signed int s32_t;
+typedef signed long long s64_t;
+
+typedef float f32_t;
+typedef double f64_t;
+typedef float _Complex c32_t;
+typedef double _Complex c64_t;
+
+u8_t u8;
+u16_t u16;
+u32_t u32;
+u64_t u64;
+
+s8_t s8;
+s16_t s16;
+s32_t s32;
+s64_t s64;
+
+struct {
+ unsigned u8:8;
+ unsigned u9:9;
+ unsigned u10:10;
+ unsigned u32:32;
+ int s8:8;
+ int s9:9;
+ int s10:10;
+ int s32:32;
+} bits;
+
+f32_t f32;
+f64_t f64;
+
+c32_t c32;
+c64_t c64;
+
+char *str;
+const char *cstr;
+
int
Q1(double dbl)
{
@@ -27,8 +71,7 @@
int
Q2(double dbl)
{
- /* expect+2: cast from floating point 'double' to integer 'int' [Q2] */
- /* expect+1: redundant cast from 'double' to 'int' before assignment [Q7] */
+ /* expect+1: cast from floating point 'double' to integer 'int' [Q2] */
return (int)dbl;
}
@@ -83,19 +126,85 @@
i = (int)i + 1;
}
-extern void *allocate(unsigned long);
+extern void *allocate(void);
-char *
+void
Q7(void)
{
- /* expect+1: redundant cast from 'pointer to void' to 'pointer to char' before assignment [Q7] */
- char *str = (char *)allocate(64);
+
+ /* expect+2: no-op cast from 'unsigned char' to 'unsigned char' [Q6] */
+ /* expect+1: redundant cast from 'unsigned char' to 'unsigned char' before assignment [Q7] */
+ u8 = (u8_t)u8;
+ u8 = (u8_t)u16;
+ u8 = (u16_t)u8;
+ /* expect+1: no-op cast from 'unsigned short' to 'unsigned short' [Q6] */
+ u8 = (u16_t)u16;
+ /* expect+1: no-op cast from 'unsigned char' to 'unsigned char' [Q6] */
+ u16 = (u8_t)u8;
+ u16 = (u8_t)u16;
+ /* expect+1: redundant cast from 'unsigned char' to 'unsigned short' before assignment [Q7] */
+ u16 = (u16_t)u8;
+ /* expect+2: no-op cast from 'unsigned short' to 'unsigned short' [Q6] */
+ /* expect+1: redundant cast from 'unsigned short' to 'unsigned short' before assignment [Q7] */
+ u16 = (u16_t)u16;
+
+ /* Mixing signed and unsigned types. */
+ u8 = (u8_t)s8;
+ s8 = (s8_t)u8;
+ /* expect+1: redundant cast from 'unsigned char' to 'short' before assignment [Q7] */
+ s16 = (s16_t)u8;
+ /* expect+1: redundant cast from 'signed char' to 'short' before assignment [Q7] */
+ s16 = (s16_t)s8;
+
+
+ /*
+ * Neither GCC nor Clang accept typeof(bit-field), as that would add
+ * unnecessary complexity. Lint accepts it but silently discards the
+ * bit-field portion from the type; see add_type.
+ */
+ /* expect+1: redundant cast from 'unsigned char' to 'unsigned int' before assignment [Q7] */
+ bits.u9 = (typeof(bits.u9))u8;
+
- if (str == (void *)0)
- /* expect+1: redundant cast from 'pointer to void' to 'pointer to char' before assignment [Q7] */
- str = (char *)allocate(64);
+ /* expect+2: no-op cast from 'float' to 'float' [Q6] */
+ /* expect+1: redundant cast from 'float' to 'float' before assignment [Q7] */
+ f32 = (f32_t)f32;
+ f32 = (f32_t)f64;
+ f32 = (f64_t)f32;
+ /* expect+1: no-op cast from 'double' to 'double' [Q6] */
+ f32 = (f64_t)f64;
+ /* expect+1: no-op cast from 'float' to 'float' [Q6] */
+ f64 = (f32_t)f32;
+ f64 = (f32_t)f64;
+ /* expect+1: redundant cast from 'float' to 'double' before assignment [Q7] */
+ f64 = (f64_t)f32;
+ /* expect+2: no-op cast from 'double' to 'double' [Q6] */
+ /* expect+1: redundant cast from 'double' to 'double' before assignment [Q7] */
+ f64 = (f64_t)f64;
+
- return str;
+ /* expect+2: no-op cast from 'float _Complex' to 'float _Complex' [Q6] */
+ /* expect+1: redundant cast from 'float _Complex' to 'float _Complex' before assignment [Q7] */
+ c32 = (c32_t)c32;
+ c32 = (c32_t)c64;
+ c32 = (c64_t)c32;
+ /* expect+1: no-op cast from 'double _Complex' to 'double _Complex' [Q6] */
+ c32 = (c64_t)c64;
+ /* expect+1: no-op cast from 'float _Complex' to 'float _Complex' [Q6] */
+ c64 = (c32_t)c32;
+ c64 = (c32_t)c64;
+ /* expect+1: redundant cast from 'float _Complex' to 'double _Complex' before assignment [Q7] */
+ c64 = (c64_t)c32;
+ /* expect+2: no-op cast from 'double _Complex' to 'double _Complex' [Q6] */
+ /* expect+1: redundant cast from 'double _Complex' to 'double _Complex' before assignment [Q7] */
+ c64 = (c64_t)c64;
+
+
+ /* expect+1: redundant cast from 'pointer to void' to 'pointer to char' before assignment [Q7] */
+ str = (char *)allocate();
+ /* expect+1: redundant cast from 'pointer to void' to 'pointer to const char' before assignment [Q7] */
+ cstr = (const char *)allocate();
+ cstr = (char *)allocate();
}
diff -r 315c7497dab3 -r 57929c3ed368 usr.bin/xlint/lint1/README.md
--- a/usr.bin/xlint/lint1/README.md Fri Jul 08 17:47:47 2022 +0000
+++ b/usr.bin/xlint/lint1/README.md Fri Jul 08 20:27:36 2022 +0000
@@ -1,4 +1,4 @@
-[//]: # ($NetBSD: README.md,v 1.8 2022/07/05 22:50:41 rillig Exp $)
+[//]: # ($NetBSD: README.md,v 1.9 2022/07/08 20:27:36 rillig Exp $)
# Introduction
@@ -161,15 +161,16 @@
Useful breakpoints are:
-| Function | File | Remarks |
-|---------------------|--------|------------------------------------------------------|
-| build_binary | tree.c | Creates an expression for a unary or binary operator |
-| initialization_expr | init.c | Checks a single initializer |
-| expr | tree.c | Checks a full expression |
-| typeok | tree.c | Checks two types for compatibility |
-| vwarning_at | err.c | Prints a warning |
-| verror_at | err.c | Prints an error |
-| assert_failed | err.c | Prints the location of a failed assertion |
+| Function/Code | File | Remarks |
+|---------------------|---------|------------------------------------------------------|
+| build_binary | tree.c | Creates an expression for a unary or binary operator |
+| initialization_expr | init.c | Checks a single initializer |
+| expr | tree.c | Checks a full expression |
+| typeok | tree.c | Checks two types for compatibility |
+| vwarning_at | err.c | Prints a warning |
+| verror_at | err.c | Prints an error |
+| assert_failed | err.c | Prints the location of a failed assertion |
+| `switch (yyn)` | cgram.c | Reduction of a grammar rule |
# Tests
diff -r 315c7497dab3 -r 57929c3ed368 usr.bin/xlint/lint1/tree.c
--- a/usr.bin/xlint/lint1/tree.c Fri Jul 08 17:47:47 2022 +0000
+++ b/usr.bin/xlint/lint1/tree.c Fri Jul 08 20:27:36 2022 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: tree.c,v 1.472 2022/07/06 22:26:30 rillig Exp $ */
+/* $NetBSD: tree.c,v 1.473 2022/07/08 20:27:36 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.472 2022/07/06 22:26:30 rillig Exp $");
+__RCSID("$NetBSD: tree.c,v 1.473 2022/07/08 20:27:36 rillig Exp $");
#endif
#include <float.h>
@@ -116,6 +116,14 @@
return x;
}
+static unsigned
+width_in_bits(const type_t *tp)
+{
+
+ lint_assert(is_integer(tp->t_tspec));
+ return tp->t_bitfield ? tp->t_flen : size_in_bits(tp->t_tspec);
+}
+
static bool
ic_maybe_signed(const type_t *tp, const integer_constraints *ic)
{
@@ -124,20 +132,12 @@
(ic->bclr & ((uint64_t)1 << 63)) == 0;
}
-static unsigned
-ic_length_in_bits(const type_t *tp)
-{
-
- lint_assert(is_integer(tp->t_tspec));
- return tp->t_bitfield ? tp->t_flen : size_in_bits(tp->t_tspec);
-}
-
static integer_constraints
ic_any(const type_t *tp)
{
integer_constraints c;
- uint64_t vbits = value_bits(ic_length_in_bits(tp));
+ uint64_t vbits = value_bits(width_in_bits(tp));
if (is_uinteger(tp->t_tspec)) {
c.smin = INT64_MIN;
c.smax = INT64_MAX;
@@ -177,7 +177,7 @@
ic_cvt(const type_t *ntp, const type_t *otp, integer_constraints a)
{
- if (ic_length_in_bits(ntp) > ic_length_in_bits(otp) &&
+ if (width_in_bits(ntp) > width_in_bits(otp) &&
is_uinteger(otp->t_tspec))
return a;
return ic_any(ntp);
@@ -2476,7 +2476,7 @@
debug_step("%s: type '%s'", __func__, type_name(tp));
debug_node(tn);
- uint64_t nmask = value_bits(ic_length_in_bits(tp));
+ uint64_t nmask = value_bits(width_in_bits(tp));
if (!is_uinteger(tp->t_tspec))
nmask >>= 1;
@@ -3351,6 +3351,42 @@
return ntn;
}
+static bool
+is_cast_redundant(const tnode_t *tn)
+{
+ const type_t *ntp = tn->tn_type, *otp = tn->tn_left->tn_type;
+ tspec_t nt = ntp->t_tspec, ot = otp->t_tspec;
+
+ if (nt == BOOL && ot == BOOL)
+ return true;
+
+ if (is_integer(nt) && is_integer(ot)) {
+ unsigned int nw = width_in_bits(ntp), ow = width_in_bits(otp);
+ if (is_uinteger(nt) == is_uinteger(ot))
+ return nw >= ow;
+ return is_uinteger(ot) && nw > ow;
+ }
+
+ if (is_floating(nt) && is_floating(ot))
+ return size_in_bits(nt) >= size_in_bits(ot);
+
+ if (is_complex(nt) && is_complex(ot))
+ return size_in_bits(nt) >= size_in_bits(ot);
+
+ if (nt == PTR && ot == PTR) {
+ if (!ntp->t_subt->t_const && otp->t_subt->t_const)
Home |
Main Index |
Thread Index |
Old Index