Module Name:    src
Committed By:   rillig
Date:           Fri Jul  8 21:19:07 UTC 2022

Modified Files:
        src/tests/usr.bin/xlint/lint1: queries.c
        src/usr.bin/xlint/common: inittyp.c
        src/usr.bin/xlint/lint1: tree.c

Log Message:
lint: fix edge cases in the query for redundant cast before assignment

Casting from and to _Bool is only allowed outside strict bool mode.
Outside strict bool mode, _Bool is an integer type, therefore return
early if any of the operands has type _Bool.  In strict bool mode, even
casting from _Bool to _Bool is not allowed, as it is not needed in
practice.

Handle _Complex types before real floating-point types.  Return early
for _Complex types, as these are floating-point types as well.

For pointer casts, not only flag casts to or from 'pointer to void', but
also casts between the same types.

In debug mode, when constructing the type '_Complex float', the type
name of '_Complex' occurs in the debug log.  Outside of debug mode,
printing this type name is an error since this type keyword only occurs
internally, when constructing a type.  At that point, it is not supposed
to occur in any user-visible message.


To generate a diff of this commit:
cvs rdiff -u -r1.2 -r1.3 src/tests/usr.bin/xlint/lint1/queries.c
cvs rdiff -u -r1.31 -r1.32 src/usr.bin/xlint/common/inittyp.c
cvs rdiff -u -r1.473 -r1.474 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/queries.c
diff -u src/tests/usr.bin/xlint/lint1/queries.c:1.2 src/tests/usr.bin/xlint/lint1/queries.c:1.3
--- src/tests/usr.bin/xlint/lint1/queries.c:1.2	Fri Jul  8 20:27:36 2022
+++ src/tests/usr.bin/xlint/lint1/queries.c	Fri Jul  8 21:19:07 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: queries.c,v 1.2 2022/07/08 20:27:36 rillig Exp $	*/
+/*	$NetBSD: queries.c,v 1.3 2022/07/08 21:19:07 rillig Exp $	*/
 # 3 "queries.c"
 
 /*
@@ -31,6 +31,12 @@ typedef double f64_t;
 typedef float _Complex c32_t;
 typedef double _Complex c64_t;
 
+typedef char *str_t;
+typedef const char *cstr_t;
+typedef volatile char *vstr_t;
+
+_Bool cond;
+
 u8_t u8;
 u16_t u16;
 u32_t u32;
@@ -60,6 +66,7 @@ c64_t c64;
 
 char *str;
 const char *cstr;
+volatile char *vstr;
 
 int
 Q1(double dbl)
@@ -132,6 +139,12 @@ void
 Q7(void)
 {
 
+	/* expect+2: no-op cast from '_Bool' to '_Bool' [Q6] */
+	/* expect+1: redundant cast from '_Bool' to '_Bool' before assignment [Q7] */
+	cond = (_Bool)cond;
+	cond = (_Bool)u8;
+	u8 = (u8_t)cond;
+
 	/* 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;
@@ -200,11 +213,56 @@ Q7(void)
 	c64 = (c64_t)c64;
 
 
+	/* Mixing real and complex floating point types. */
+	/* expect+1: no-op cast from 'float' to 'float' [Q6] */
+	c32 = (f32_t)f32;
+	c32 = (c32_t)f32;
+	/* expect+1: no-op cast from 'float' to 'float' [Q6] */
+	c64 = (f32_t)f32;
+	c64 = (f64_t)f32;
+	c64 = (c32_t)f32;
+	c64 = (c64_t)f32;
+
+
 	/* 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();
+
+	/* expect+2: no-op cast from 'pointer to char' to 'pointer to char' [Q6] */
+	/* expect+1: redundant cast from 'pointer to char' to 'pointer to char' before assignment [Q7] */
+	str = (str_t)str;
+	str = (str_t)cstr;
+	/* expect+1: warning: operands of '=' have incompatible pointer types to 'char' and 'const char' [128] */
+	str = (cstr_t)str;
+	/* expect+2: no-op cast from 'pointer to const char' to 'pointer to const char' [Q6] */
+	/* expect+1: warning: operands of '=' have incompatible pointer types to 'char' and 'const char' [128] */
+	str = (cstr_t)cstr;
+	/* expect+1: no-op cast from 'pointer to char' to 'pointer to char' [Q6] */
+	cstr = (str_t)str;
+	cstr = (str_t)cstr;
+	cstr = (cstr_t)str;
+	/* expect+2: no-op cast from 'pointer to const char' to 'pointer to const char' [Q6] */
+	/* expect+1: redundant cast from 'pointer to const char' to 'pointer to const char' before assignment [Q7] */
+	cstr = (cstr_t)cstr;
+
+	/* expect+2: no-op cast from 'pointer to char' to 'pointer to char' [Q6] */
+	/* expect+1: redundant cast from 'pointer to char' to 'pointer to char' before assignment [Q7] */
+	str = (str_t)str;
+	str = (str_t)vstr;
+	/* expect+1: warning: operands of '=' have incompatible pointer types to 'char' and 'volatile char' [128] */
+	str = (vstr_t)str;
+	/* expect+2: no-op cast from 'pointer to volatile char' to 'pointer to volatile char' [Q6] */
+	/* expect+1: warning: operands of '=' have incompatible pointer types to 'char' and 'volatile char' [128] */
+	str = (vstr_t)vstr;
+	/* expect+1: no-op cast from 'pointer to char' to 'pointer to char' [Q6] */
+	vstr = (str_t)str;
+	vstr = (str_t)vstr;
+	vstr = (vstr_t)str;
+	/* expect+2: no-op cast from 'pointer to volatile char' to 'pointer to volatile char' [Q6] */
+	/* expect+1: redundant cast from 'pointer to volatile char' to 'pointer to volatile char' before assignment [Q7] */
+	vstr = (vstr_t)vstr;
 }
 
 

Index: src/usr.bin/xlint/common/inittyp.c
diff -u src/usr.bin/xlint/common/inittyp.c:1.31 src/usr.bin/xlint/common/inittyp.c:1.32
--- src/usr.bin/xlint/common/inittyp.c:1.31	Fri May 20 21:18:54 2022
+++ src/usr.bin/xlint/common/inittyp.c	Fri Jul  8 21:19:06 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: inittyp.c,v 1.31 2022/05/20 21:18:54 rillig Exp $	*/
+/*	$NetBSD: inittyp.c,v 1.32 2022/07/08 21:19:06 rillig Exp $	*/
 
 /*
  * Copyright (c) 1994, 1995 Jochen Pohl
@@ -37,7 +37,7 @@
 
 #include <sys/cdefs.h>
 #if defined(__RCSID)
-__RCSID("$NetBSD: inittyp.c,v 1.31 2022/05/20 21:18:54 rillig Exp $");
+__RCSID("$NetBSD: inittyp.c,v 1.32 2022/07/08 21:19:06 rillig Exp $");
 #endif
 
 #if defined(IS_LINT1)
@@ -124,7 +124,11 @@ ttab_t	ttab[NTSPEC] = {
 	    0, 1, 0, 0, 1, 0),
 	typeinfo("array", ARRAY, ARRAY, 0, 0, 0, 0, 0, 0, 0, 0),
 	typeinfo("function", FUNC, FUNC, 0, 0, 0, 0, 0, 0, 0, 0),
+#ifdef DEBUG
+	typeinfo("_Complex", NOTSPEC, NOTSPEC, 0, 0, 0, 0, 0, 0, 0, 0),
+#else
 	typeinfo(NULL, NOTSPEC, NOTSPEC, 0, 0, 0, 0, 0, 0, 0, 0),
+#endif
 	typeinfo("float _Complex", FCOMPLEX, FCOMPLEX,
 	    FLOAT_SIZE * 2, 32 * 2, 0, 0, 1, 1, 1, 1),
 	typeinfo("double _Complex", DCOMPLEX, DCOMPLEX,

Index: src/usr.bin/xlint/lint1/tree.c
diff -u src/usr.bin/xlint/lint1/tree.c:1.473 src/usr.bin/xlint/lint1/tree.c:1.474
--- src/usr.bin/xlint/lint1/tree.c:1.473	Fri Jul  8 20:27:36 2022
+++ src/usr.bin/xlint/lint1/tree.c	Fri Jul  8 21:19:07 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: tree.c,v 1.473 2022/07/08 20:27:36 rillig Exp $	*/
+/*	$NetBSD: tree.c,v 1.474 2022/07/08 21:19:07 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.473 2022/07/08 20:27:36 rillig Exp $");
+__RCSID("$NetBSD: tree.c,v 1.474 2022/07/08 21:19:07 rillig Exp $");
 #endif
 
 #include <float.h>
@@ -3357,8 +3357,8 @@ 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 (nt == BOOL || ot == BOOL)
+		return nt == BOOL && ot == BOOL;
 
 	if (is_integer(nt) && is_integer(ot)) {
 		unsigned int nw = width_in_bits(ntp), ow = width_in_bits(otp);
@@ -3367,10 +3367,11 @@ is_cast_redundant(const tnode_t *tn)
 		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 is_complex(nt) && is_complex(ot) &&
+		       size_in_bits(nt) >= size_in_bits(ot);
 
-	if (is_complex(nt) && is_complex(ot))
+	if (is_floating(nt) && is_floating(ot))
 		return size_in_bits(nt) >= size_in_bits(ot);
 
 	if (nt == PTR && ot == PTR) {
@@ -3380,7 +3381,8 @@ is_cast_redundant(const tnode_t *tn)
 			return false;
 
 		if (ntp->t_subt->t_tspec == VOID ||
-		    otp->t_subt->t_tspec == VOID)
+		    otp->t_subt->t_tspec == VOID ||
+		    eqtype(ntp->t_subt, otp->t_subt, false, false, NULL))
 			return true;
 	}
 

Reply via email to