summaryrefslogtreecommitdiff
path: root/usr.bin/xlint/lint1/tree.c
diff options
context:
space:
mode:
authorrillig <rillig@NetBSD.org>2023-05-09 15:51:33 +0000
committerrillig <rillig@NetBSD.org>2023-05-09 15:51:33 +0000
commit9c79005f8eaf6c18cb92622ef27dc8a767e6b7c8 (patch)
treeb13738d0f657cce4bfb31293d203a3dce12ee879 /usr.bin/xlint/lint1/tree.c
parent5b67ea519dc93d9663b6c9847e629da5880b12e3 (diff)
lint: track integer constraints through conditional expressions
Diffstat (limited to 'usr.bin/xlint/lint1/tree.c')
-rw-r--r--usr.bin/xlint/lint1/tree.c28
1 files changed, 26 insertions, 2 deletions
diff --git a/usr.bin/xlint/lint1/tree.c b/usr.bin/xlint/lint1/tree.c
index bfa1d06ecea..fb64f554ee2 100644
--- a/usr.bin/xlint/lint1/tree.c
+++ b/usr.bin/xlint/lint1/tree.c
@@ -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_constraints a, integer_constraints b)
}
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 tnode_t *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;
}