Module Name:    src
Committed By:   rillig
Date:           Tue Mar 12 07:56:08 UTC 2024

Modified Files:
        src/tests/usr.bin/xlint/lint1: msg_132.c msg_267.c
        src/usr.bin/xlint/lint1: tree.c

Log Message:
lint: fix warning about loss of conversion for unsigned bit-fields

Since decl.c 1.180 from 2021-05-02.


To generate a diff of this commit:
cvs rdiff -u -r1.34 -r1.35 src/tests/usr.bin/xlint/lint1/msg_132.c
cvs rdiff -u -r1.7 -r1.8 src/tests/usr.bin/xlint/lint1/msg_267.c
cvs rdiff -u -r1.623 -r1.624 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_132.c
diff -u src/tests/usr.bin/xlint/lint1/msg_132.c:1.34 src/tests/usr.bin/xlint/lint1/msg_132.c:1.35
--- src/tests/usr.bin/xlint/lint1/msg_132.c:1.34	Tue Mar 12 07:29:39 2024
+++ src/tests/usr.bin/xlint/lint1/msg_132.c	Tue Mar 12 07:56:08 2024
@@ -1,4 +1,4 @@
-/*	$NetBSD: msg_132.c,v 1.34 2024/03/12 07:29:39 rillig Exp $	*/
+/*	$NetBSD: msg_132.c,v 1.35 2024/03/12 07:56:08 rillig Exp $	*/
 # 3 "msg_132.c"
 
 // Test for message: conversion from '%s' to '%s' may lose accuracy [132]
@@ -410,11 +410,10 @@ fp_classify(void)
 		unsigned long long ext_exp:15;
 	} x;
 
-	/* FIXME: There is no loss of accuracy here. */
-	/* expect+1: warning: conversion from 'unsigned long long:15' to 'int:15' may lose accuracy [132] */
+	// Since decl.c 1.180 from 2021-05-02 and before tree.c 1.624 from
+	// 2024-03-12, lint warned about a possible loss of accuracy [132]
+	// when promoting a small unsigned bit-field to 'int'.
 	if (x.ext_exp == 0) {
-	/* FIXME: There is no loss of accuracy here. */
-	/* expect+1: warning: conversion from 'unsigned long long:15' to 'int:15' may lose accuracy [132] */
 	} else if (x.ext_exp == 0x7fff) {
 	}
 }

Index: src/tests/usr.bin/xlint/lint1/msg_267.c
diff -u src/tests/usr.bin/xlint/lint1/msg_267.c:1.7 src/tests/usr.bin/xlint/lint1/msg_267.c:1.8
--- src/tests/usr.bin/xlint/lint1/msg_267.c:1.7	Fri Jul  7 19:45:22 2023
+++ src/tests/usr.bin/xlint/lint1/msg_267.c	Tue Mar 12 07:56:08 2024
@@ -1,4 +1,4 @@
-/*	$NetBSD: msg_267.c,v 1.7 2023/07/07 19:45:22 rillig Exp $	*/
+/*	$NetBSD: msg_267.c,v 1.8 2024/03/12 07:56:08 rillig Exp $	*/
 # 3 "msg_267.c"
 
 // Test for message: shift amount %u equals bit-size of '%s' [267]
@@ -57,20 +57,28 @@ shift_bit_field(void)
 	    (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] */
+	    // When promoting 'unsigned int:18', the target type is 'int', as
+	    // it can represent all possible values; this is a bit misleading
+	    // as its sign bit is always 0.
+	    /* expect+1: warning: shift amount 32 equals bit-size of 'int:19' [267] */
 	    (s.bit_field >> 32) &
-	    /* XXX: Why 'int', not 'unsigned int:18'? */
+	    // When promoting 'unsigned int:18', the target type is 'int', as
+	    // it can represent all possible values; this is a bit misleading
+	    // as its sign bit is always 0.
 	    /* 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] */
+	    // When promoting 'unsigned int:18', the target type is 'int', as
+	    // it can represent all possible values; this is a bit misleading
+	    // as its sign bit is always 0.
+	    /* expect+1: warning: shift amount 32 equals bit-size of 'int:19' [267] */
 	    (s.bit_field << 32) &
-	    /* XXX: Why 'int', not 'unsigned int:18'? */
+	    // When promoting 'unsigned int:18', the target type is 'int', as
+	    // it can represent all possible values; this is a bit misleading
+	    // as its sign bit is always 0.
 	    /* expect+1: warning: shift amount 33 is greater than bit-size 32 of 'int' [122] */
 	    (s.bit_field << 33) &
 	    15;

Index: src/usr.bin/xlint/lint1/tree.c
diff -u src/usr.bin/xlint/lint1/tree.c:1.623 src/usr.bin/xlint/lint1/tree.c:1.624
--- src/usr.bin/xlint/lint1/tree.c:1.623	Sun Mar 10 19:45:14 2024
+++ src/usr.bin/xlint/lint1/tree.c	Tue Mar 12 07:56:08 2024
@@ -1,4 +1,4 @@
-/*	$NetBSD: tree.c,v 1.623 2024/03/10 19:45:14 rillig Exp $	*/
+/*	$NetBSD: tree.c,v 1.624 2024/03/12 07:56:08 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.623 2024/03/10 19:45:14 rillig Exp $");
+__RCSID("$NetBSD: tree.c,v 1.624 2024/03/12 07:56:08 rillig Exp $");
 #endif
 
 #include <float.h>
@@ -3256,7 +3256,8 @@ tnode_t *
 promote(op_t op, bool farg, tnode_t *tn)
 {
 
-	tspec_t ot = tn->tn_type->t_tspec;
+	const type_t *otp = tn->tn_type;
+	tspec_t ot = otp->t_tspec;
 	if (!is_arithmetic(ot))
 		return tn;
 
@@ -3264,12 +3265,18 @@ promote(op_t op, bool farg, tnode_t *tn)
 	if (nt == ot)
 		return tn;
 
-	type_t *ntp = expr_dup_type(tn->tn_type);
+	type_t *ntp = expr_dup_type(gettyp(nt));
 	ntp->t_tspec = nt;
-	/*
-	 * Keep t_is_enum even though t_tspec gets converted from ENUM to INT,
-	 * so we are later able to check compatibility of enum types.
-	 */
+	ntp->t_is_enum = otp->t_is_enum;
+	if (ntp->t_is_enum)
+		ntp->u.enumer = otp->u.enumer;
+	ntp->t_bitfield = otp->t_bitfield;
+	if (ntp->t_bitfield) {
+		ntp->t_bit_field_width = otp->t_bit_field_width;
+		ntp->t_bit_field_offset = otp->t_bit_field_offset;
+	}
+	if (ntp->t_bitfield && is_uinteger(ot) && !is_uinteger(nt))
+		ntp->t_bit_field_width++;
 	return convert(op, 0, ntp, tn);
 }
 

Reply via email to