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: replace array access with function...



details:   https://anonhg.NetBSD.org/src/rev/7464df579271
branches:  trunk
changeset: 379711:7464df579271
user:      rillig <rillig%NetBSD.org@localhost>
date:      Tue Jun 15 20:46:45 2021 +0000

description:
lint: replace array access with function calls

First and foremost, the test d_c99_complex_split accessed the array
qlmasks out-of-bounds, with an index of 128 for the type 'double
_Complex'.  This invoked undefined behavior since the maximum allowed
index was 64.

Replacing the raw array accesses with function calls allows for bounds
checks to catch these errors early.

Determining the value bits for a 'double _Complex' does not make sense
at all since it is not an integer type.  This means that lint didn't
handle these types correctly for several years.  Support for int128_t
has been added in inittyp.c 1.12 from 2018-09-07, support for _Complex
has been added in inittyp.c 1.9 from 2008-04-26.

Determining the value bits for an int128_t would make sense, but the
unit tests don't contain examples for this type since at the moment all
unit tests must produce the same results on 32-bit and 64-bit platforms,
and the 32-bit platforms don't support int128_t.

diffstat:

 usr.bin/xlint/lint1/externs1.h |   3 +--
 usr.bin/xlint/lint1/lex.c      |  38 ++++++++------------------------------
 usr.bin/xlint/lint1/lint1.h    |  26 +++++++++++++++++++++++++-
 usr.bin/xlint/lint1/tree.c     |  12 ++++++------
 4 files changed, 40 insertions(+), 39 deletions(-)

diffs (192 lines):

diff -r 582dbaed5b64 -r 7464df579271 usr.bin/xlint/lint1/externs1.h
--- a/usr.bin/xlint/lint1/externs1.h    Tue Jun 15 18:54:34 2021 +0000
+++ b/usr.bin/xlint/lint1/externs1.h    Tue Jun 15 20:46:45 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: externs1.h,v 1.108 2021/04/18 17:36:18 rillig Exp $    */
+/*     $NetBSD: externs1.h,v 1.109 2021/06/15 20:46:45 rillig Exp $    */
 
 /*
  * Copyright (c) 1994, 1995 Jochen Pohl
@@ -75,7 +75,6 @@ extern        pos_t   csrc_pos;
 extern bool    in_system_header;
 extern symt_t  symtyp;
 extern FILE    *yyin;
-extern uint64_t qbmasks[], qlmasks[], qumasks[];
 
 extern void    initscan(void);
 extern int     msb(int64_t, tspec_t, int);
diff -r 582dbaed5b64 -r 7464df579271 usr.bin/xlint/lint1/lex.c
--- a/usr.bin/xlint/lint1/lex.c Tue Jun 15 18:54:34 2021 +0000
+++ b/usr.bin/xlint/lint1/lex.c Tue Jun 15 20:46:45 2021 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: lex.c,v 1.36 2021/05/03 08:03:45 rillig Exp $ */
+/* $NetBSD: lex.c,v 1.37 2021/06/15 20:46:45 rillig Exp $ */
 
 /*
  * Copyright (c) 1996 Christopher G. Demetriou.  All Rights Reserved.
@@ -38,7 +38,7 @@
 
 #include <sys/cdefs.h>
 #if defined(__RCSID) && !defined(lint)
-__RCSID("$NetBSD: lex.c,v 1.36 2021/05/03 08:03:45 rillig Exp $");
+__RCSID("$NetBSD: lex.c,v 1.37 2021/06/15 20:46:45 rillig Exp $");
 #endif
 
 #include <ctype.h>
@@ -250,15 +250,6 @@ static     struct  kwtab {
 /* Symbol table */
 static sym_t   *symtab[HSHSIZ1];
 
-/* bit i of the entry with index i is set */
-uint64_t qbmasks[64];
-
-/* least significant i bits are set in the entry with index i */
-uint64_t qlmasks[64 + 1];
-
-/* least significant i bits are not set in the entry with index i */
-uint64_t qumasks[64 + 1];
-
 /* free list for sbuf structures */
 static sbuf_t   *sbfrlst;
 
@@ -321,8 +312,6 @@ void
 initscan(void)
 {
        struct  kwtab *kw;
-       size_t  i;
-       uint64_t uq;
 
        for (kw = kwtab; kw->kw_name != NULL; kw++) {
                if ((kw->kw_c89 || kw->kw_c99) && tflag)
@@ -335,16 +324,6 @@ initscan(void)
                add_keyword(kw, 2);
                add_keyword(kw, 4);
        }
-
-       /* initialize bit-masks for quads */
-       for (i = 0; i < 64; i++) {
-               qbmasks[i] = (uint64_t)1 << i;
-               uq = ~(uint64_t)0 << i;
-               qumasks[i] = uq;
-               qlmasks[i] = ~uq;
-       }
-       qumasks[i] = 0;
-       qlmasks[i] = ~(uint64_t)0;
 }
 
 /*
@@ -715,7 +694,7 @@ msb(int64_t q, tspec_t t, int len)
 
        if (len <= 0)
                len = size_in_bits(t);
-       return (q & qbmasks[len - 1]) != 0 ? 1 : 0;
+       return (q & bit(len - 1)) != 0 ? 1 : 0;
 }
 
 /*
@@ -724,16 +703,15 @@ msb(int64_t q, tspec_t t, int len)
 int64_t
 xsign(int64_t q, tspec_t t, int len)
 {
+       uint64_t vbits;
 
        if (len <= 0)
                len = size_in_bits(t);
 
-       if (t == PTR || is_uinteger(t) || !sign(q, t, len)) {
-               q &= qlmasks[len];
-       } else {
-               q |= qumasks[len];
-       }
-       return q;
+       vbits = value_bits(len);
+       return t == PTR || is_uinteger(t) || !sign(q, t, len)
+           ? q & vbits
+           : q | ~vbits;
 }
 
 /*
diff -r 582dbaed5b64 -r 7464df579271 usr.bin/xlint/lint1/lint1.h
--- a/usr.bin/xlint/lint1/lint1.h       Tue Jun 15 18:54:34 2021 +0000
+++ b/usr.bin/xlint/lint1/lint1.h       Tue Jun 15 20:46:45 2021 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: lint1.h,v 1.101 2021/05/15 19:12:14 rillig Exp $ */
+/* $NetBSD: lint1.h,v 1.102 2021/06/15 20:46:45 rillig Exp $ */
 
 /*
  * Copyright (c) 1996 Christopher G. Demetriou.  All Rights Reserved.
@@ -531,3 +531,27 @@ is_nonzero(const tnode_t *tn)
 {
        return tn != NULL && tn->tn_op == CON && is_nonzero_val(tn->tn_val);
 }
+
+static inline uint64_t
+bit(unsigned i)
+{
+       lint_assert(i < 64);
+       return (uint64_t)1 << i;
+}
+
+static inline uint64_t
+value_bits(unsigned bitsize)
+{
+       lint_assert(bitsize > 0);
+
+       /* for long double (80 or 128), double _Complex (128) */
+       /*
+        * XXX: double _Complex does not have 128 bits of precision,
+        * therefore it should never be necessary to query the value bits
+        * of such a type; see d_c99_complex_split.c to trigger this case.
+        */
+       if (bitsize >= 64)
+               return ~((uint64_t)0);
+
+       return ~(~(uint64_t)0 << bitsize);
+}
diff -r 582dbaed5b64 -r 7464df579271 usr.bin/xlint/lint1/tree.c
--- a/usr.bin/xlint/lint1/tree.c        Tue Jun 15 18:54:34 2021 +0000
+++ b/usr.bin/xlint/lint1/tree.c        Tue Jun 15 20:46:45 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: tree.c,v 1.286 2021/06/15 18:23:39 rillig Exp $        */
+/*     $NetBSD: tree.c,v 1.287 2021/06/15 20:46:45 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.286 2021/06/15 18:23:39 rillig Exp $");
+__RCSID("$NetBSD: tree.c,v 1.287 2021/06/15 20:46:45 rillig Exp $");
 #endif
 
 #include <float.h>
@@ -2203,7 +2203,7 @@ convert_constant_check_range_bitand(size
                                    const type_t *tp, op_t op)
 {
        if (nsz > osz &&
-           (nv->v_quad & qbmasks[osz - 1]) != 0 &&
+           (nv->v_quad & bit(osz - 1)) != 0 &&
            (nv->v_quad & xmask) != xmask) {
                /* extra bits set to 0 in conversion of '%s' to '%s', ... */
                warning(309, type_name(gettyp(ot)),
@@ -2315,8 +2315,8 @@ convert_constant_check_range(tspec_t ot,
 
        osz = size_in_bits(ot);
        nsz = tp->t_bitfield ? tp->t_flen : size_in_bits(nt);
-       xmask = qlmasks[nsz] ^ qlmasks[osz];
-       xmsk1 = qlmasks[nsz] ^ qlmasks[osz - 1];
+       xmask = value_bits(nsz) ^ value_bits(osz);
+       xmsk1 = value_bits(nsz) ^ value_bits(osz - 1);
        /*
         * For bitwise operations we are not interested in the
         * value, but in the bits itself.
@@ -2940,7 +2940,7 @@ fold(tnode_t *tn)
        if (modtab[tn->tn_op].m_binary)
                ur = sr = tn->tn_right->tn_val->v_quad;
 
-       mask = qlmasks[size_in_bits(t)];
+       mask = value_bits(size_in_bits(t));
        ovfl = false;
 
        switch (tn->tn_op) {



Home | Main Index | Thread Index | Old Index