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: track integer constraints through ...



details:   https://anonhg.NetBSD.org/src/rev/18e338844738
branches:  trunk
changeset: 374660:18e338844738
user:      rillig <rillig%NetBSD.org@localhost>
date:      Tue May 09 15:51:33 2023 +0000

description:
lint: track integer constraints through conditional expressions

diffstat:

 tests/usr.bin/xlint/lint1/msg_132.c |  15 +++++++++------
 usr.bin/xlint/lint1/tree.c          |  28 ++++++++++++++++++++++++++--
 2 files changed, 35 insertions(+), 8 deletions(-)

diffs (104 lines):

diff -r 889ab8844521 -r 18e338844738 tests/usr.bin/xlint/lint1/msg_132.c
--- a/tests/usr.bin/xlint/lint1/msg_132.c       Tue May 09 15:45:06 2023 +0000
+++ b/tests/usr.bin/xlint/lint1/msg_132.c       Tue May 09 15:51:33 2023 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: msg_132.c,v 1.29 2023/05/09 15:45:06 rillig Exp $      */
+/*     $NetBSD: msg_132.c,v 1.30 2023/05/09 15:51:33 rillig Exp $      */
 # 3 "msg_132.c"
 
 // Test for message: conversion from '%s' to '%s' may lose accuracy [132]
@@ -379,8 +379,6 @@ void
 test_ic_conditional(char c1, char c2)
 {
        /* Both operands are representable as char. */
-       /* FIXME */
-       /* expect+1: warning: conversion from 'int' to 'char' may lose accuracy [132] */
        ch = cond ? '?' : ':';
 
        /*
@@ -388,14 +386,19 @@ test_ic_conditional(char c1, char c2)
         * warns about a narrowing conversion from 'int' to signed type
         * 'char'.
         */
-       /* FIXME */
-       /* expect+1: warning: conversion from 'int' to 'char' may lose accuracy [132] */
        ch = cond ? c1 : c2;
 
-       /* FIXME */
+       /*
+        * Mixing s8 and u8 results in a number from -128 to 255, which does
+        * not necessarily fit into s8.
+        */
        /* expect+1: warning: conversion from 'int' to 'signed char' may lose accuracy [132] */
        s8 = cond ? s8 : u8;
 
+       /*
+        * Mixing s8 and u8 results in a number from -128 to 255, which does
+        * not necessarily fit into u8.
+        */
        /* expect+1: warning: conversion from 'int' to 'unsigned char' may lose accuracy [132] */
        u8 = cond ? s8 : u8;
 }
diff -r 889ab8844521 -r 18e338844738 usr.bin/xlint/lint1/tree.c
--- a/usr.bin/xlint/lint1/tree.c        Tue May 09 15:45:06 2023 +0000
+++ b/usr.bin/xlint/lint1/tree.c        Tue May 09 15:51:33 2023 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: tree.c,v 1.520 2023/05/09 15:45:06 rillig Exp $        */
+/*     $NetBSD: tree.c,v 1.521 2023/05/09 15:51:33 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.520 2023/05/09 15:45:06 rillig Exp $");
+__RCSID("$NetBSD: tree.c,v 1.521 2023/05/09 15:51:33 rillig Exp $");
 #endif
 
 #include <float.h>
@@ -255,6 +255,20 @@ ic_shr(const type_t *tp, integer_constra
 }
 
 static integer_constraints
+ic_cond(integer_constraints a, integer_constraints b)
+{
+       integer_constraints c;
+
+       c.smin = a.smin < b.smin ? a.smin : b.smin;
+       c.smax = a.smax > b.smax ? a.smax : b.smax;
+       c.umin = a.umin < b.umin ? a.umin : b.umin;
+       c.umax = a.umax > b.umax ? a.umax : b.umax;
+       c.bset = a.bset | b.bset;
+       c.bclr = a.bclr & b.bclr;
+       return c;
+}
+
+static integer_constraints
 ic_expr(const tnode_t *tn)
 {
        integer_constraints lc, rc;
@@ -289,6 +303,10 @@ ic_expr(const tnode_t *tn)
                lc = ic_expr(tn->tn_left);
                rc = ic_expr(tn->tn_right);
                return ic_bitor(lc, rc);
+       case QUEST:
+               lc = ic_expr(tn->tn_right->tn_left);
+               rc = ic_expr(tn->tn_right->tn_right);
+               return ic_cond(lc, rc);
        default:
                return ic_any(tn->tn_type);
        }
@@ -3363,6 +3381,12 @@ can_represent(const type_t *tp, const tn
        if ((~c.bclr & ~nmask) == 0)
                return true;
 
+       integer_constraints tpc = ic_any(tp);
+       if (is_uinteger(tp->t_tspec)
+           ? tpc.umin <= c.umin && tpc.umax >= c.umax
+           : tpc.smin <= c.smin && tpc.smax >= c.smax)
+               return true;
+
        return false;
 }
 



Home | Main Index | Thread Index | Old Index