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: do not warn about converting (1234...



details:   https://anonhg.NetBSD.org/src/rev/642e012fb519
branches:  trunk
changeset: 365706:642e012fb519
user:      rillig <rillig%NetBSD.org@localhost>
date:      Tue Apr 19 20:08:52 2022 +0000

description:
lint: do not warn about converting (1234567L & 0xFF) to unsigned char

Due to the '& 0xFF', there is no possible loss of accuracy.

diffstat:

 tests/usr.bin/xlint/lint1/msg_298.c   |   4 +--
 tests/usr.bin/xlint/lint1/msg_298.exp |   6 +---
 usr.bin/xlint/lint1/tree.c            |  36 +++++++++++++++++++++++++++++++++-
 3 files changed, 37 insertions(+), 9 deletions(-)

diffs (97 lines):

diff -r 5b60be060f19 -r 642e012fb519 tests/usr.bin/xlint/lint1/msg_298.c
--- a/tests/usr.bin/xlint/lint1/msg_298.c       Tue Apr 19 19:56:29 2022 +0000
+++ b/tests/usr.bin/xlint/lint1/msg_298.c       Tue Apr 19 20:08:52 2022 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: msg_298.c,v 1.3 2022/04/19 19:56:29 rillig Exp $       */
+/*     $NetBSD: msg_298.c,v 1.4 2022/04/19 20:08:52 rillig Exp $       */
 # 3 "msg_298.c"
 
 // Test for message: conversion from '%s' to '%s' may lose accuracy, arg #%d [298]
@@ -13,12 +13,10 @@
 {
        /* expect+1: warning: conversion from 'long' to 'unsigned char' may lose accuracy, arg #1 [298] */
        take_uchar(l);
-       /* expect+1: warning: conversion from 'long' to 'unsigned char' may lose accuracy, arg #1 [298] */
        take_uchar(l & 0xFF);
        /* expect+1: warning: conversion from 'long' to 'unsigned char' may lose accuracy, arg #1 [298] */
        take_uchar(l & 0x100);
        /* expect+1: warning: conversion from 'long' to 'signed char' may lose accuracy, arg #1 [298] */
        take_schar(l & 0xFF);
-       /* expect+1: warning: conversion from 'long' to 'signed char' may lose accuracy, arg #1 [298] */
        take_schar(l & 0x7F);
 }
diff -r 5b60be060f19 -r 642e012fb519 tests/usr.bin/xlint/lint1/msg_298.exp
--- a/tests/usr.bin/xlint/lint1/msg_298.exp     Tue Apr 19 19:56:29 2022 +0000
+++ b/tests/usr.bin/xlint/lint1/msg_298.exp     Tue Apr 19 20:08:52 2022 +0000
@@ -1,5 +1,3 @@
 msg_298.c(15): warning: conversion from 'long' to 'unsigned char' may lose accuracy, arg #1 [298]
-msg_298.c(17): warning: conversion from 'long' to 'unsigned char' may lose accuracy, arg #1 [298]
-msg_298.c(19): warning: conversion from 'long' to 'unsigned char' may lose accuracy, arg #1 [298]
-msg_298.c(21): warning: conversion from 'long' to 'signed char' may lose accuracy, arg #1 [298]
-msg_298.c(23): warning: conversion from 'long' to 'signed char' may lose accuracy, arg #1 [298]
+msg_298.c(18): warning: conversion from 'long' to 'unsigned char' may lose accuracy, arg #1 [298]
+msg_298.c(20): warning: conversion from 'long' to 'signed char' may lose accuracy, arg #1 [298]
diff -r 5b60be060f19 -r 642e012fb519 usr.bin/xlint/lint1/tree.c
--- a/usr.bin/xlint/lint1/tree.c        Tue Apr 19 19:56:29 2022 +0000
+++ b/usr.bin/xlint/lint1/tree.c        Tue Apr 19 20:08:52 2022 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: tree.c,v 1.433 2022/04/16 22:21:10 rillig Exp $        */
+/*     $NetBSD: tree.c,v 1.434 2022/04/19 20:08:52 rillig Exp $        */
 
 /*
  * Copyright (c) 1994, 1995 Jochen Pohl
@@ -37,7 +37,7 @@
 
 #include <sys/cdefs.h>
 #if defined(__RCSID) && !defined(lint)
-__RCSID("$NetBSD: tree.c,v 1.433 2022/04/16 22:21:10 rillig Exp $");
+__RCSID("$NetBSD: tree.c,v 1.434 2022/04/19 20:08:52 rillig Exp $");
 #endif
 
 #include <float.h>
@@ -2176,6 +2176,37 @@
 }
 
 /*
+ * When converting a large integer type to a small integer type, in some
+ * cases the value of the actual expression is further restricted than the
+ * type bounds, such as in (expr & 0xFF) or (expr % 100) or (expr >> 24).
+ *
+ * See new_tnode, the '#if 0' code for SHR.
+ */
+static bool
+can_represent(const type_t *tp, const tnode_t *tn)
+{
+
+       if (tn->tn_op == BITAND) {
+               const tnode_t *rn = tn->tn_right;
+               tspec_t nt;
+
+               if (!(rn != NULL && rn->tn_op == CON &&
+                     is_integer(rn->tn_type->t_tspec)))
+                       return false;
+
+               uint64_t nmask = value_bits(size_in_bits(nt = tp->t_tspec));
+               if (!is_uinteger(nt))
+                       nmask >>= 1;
+
+               uint64_t omask = (uint64_t)rn->tn_val->v_quad;
+               if ((omask & ~nmask) == 0)
+                       return true;
+       }
+
+       return false;
+}
+
+/*
  * Print warnings for conversions of integer types which may cause problems.
  */
 static void
@@ -2214,6 +2245,7 @@
 
        if (aflag > 0 &&
            portable_size_in_bits(nt) < portable_size_in_bits(ot) &&
+           !can_represent(tp, tn) &&
            (ot == LONG || ot == ULONG || ot == QUAD || ot == UQUAD ||
             aflag > 1)) {
                if (op == FARG) {



Home | Main Index | Thread Index | Old Index