Module Name: src Committed By: rillig Date: Tue Jun 15 17:13:08 UTC 2021
Modified Files: src/usr.bin/xlint/lint1: tree.c Log Message: lint: extract convert_constant_check_range No functional change. To generate a diff of this commit: cvs rdiff -u -r1.282 -r1.283 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/usr.bin/xlint/lint1/tree.c diff -u src/usr.bin/xlint/lint1/tree.c:1.282 src/usr.bin/xlint/lint1/tree.c:1.283 --- src/usr.bin/xlint/lint1/tree.c:1.282 Tue Jun 15 16:56:00 2021 +++ src/usr.bin/xlint/lint1/tree.c Tue Jun 15 17:13:08 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: tree.c,v 1.282 2021/06/15 16:56:00 rillig Exp $ */ +/* $NetBSD: tree.c,v 1.283 2021/06/15 17:13:08 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.282 2021/06/15 16:56:00 rillig Exp $"); +__RCSID("$NetBSD: tree.c,v 1.283 2021/06/15 17:13:08 rillig Exp $"); #endif #include <float.h> @@ -2160,6 +2160,134 @@ convert_constant_floating(const op_t op, } } +static void +convert_constant_check_range(tspec_t const ot, const type_t *const tp, + tspec_t const nt, + op_t const op, int const arg, + const val_t *const v, val_t *const nv) +{ + int osz, nsz; + int64_t xmask, xmsk1; + + 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]; + /* + * For bitwise operations we are not interested in the + * value, but in the bits itself. + */ + if (op == ORASS || op == BITOR || op == BITXOR) { + /* + * Print a warning if bits which were set are + * lost due to the conversion. + * This can happen with operator ORASS only. + */ + if (nsz < osz && (v->v_quad & xmask) != 0) { + /* constant truncated by conv., op %s */ + warning(306, op_name(op)); + } + } else if (op == ANDASS || op == BITAND) { + /* + * Print a warning if additional bits are not all 1 + * and the most significant bit of the old value is 1, + * or if at least one (but not all) removed bit was 0. + */ + if (nsz > osz && + (nv->v_quad & qbmasks[osz - 1]) != 0 && + (nv->v_quad & xmask) != xmask) { + /* extra bits set to 0 in conv. of '%s' ... */ + warning(309, type_name(gettyp(ot)), + type_name(tp), op_name(op)); + } else if (nsz < osz && + (v->v_quad & xmask) != xmask && + (v->v_quad & xmask) != 0) { + /* constant truncated by conv., op %s */ + warning(306, op_name(op)); + } + } else if ((nt != PTR && is_uinteger(nt)) && + (ot != PTR && !is_uinteger(ot)) && + v->v_quad < 0) { + if (op == ASSIGN) { + /* assignment of negative constant to ... */ + warning(164); + } else if (op == INIT) { + /* initialization of unsigned with neg... */ + warning(221); + } else if (op == FARG) { + /* conversion of negative constant to ... */ + warning(296, arg); + } else if (modtab[op].m_comparison) { + /* handled by check_integer_comparison() */ + } else { + /* conversion of negative constant to ... */ + warning(222); + } + } else if (nv->v_quad != v->v_quad && nsz <= osz && + (v->v_quad & xmask) != 0 && + (is_uinteger(ot) || (v->v_quad & xmsk1) != xmsk1)) { + /* + * Loss of significant bit(s). All truncated bits + * of unsigned types or all truncated bits plus the + * msb of the target for signed types are considered + * to be significant bits. Loss of significant bits + * means that at least on of the bits was set in an + * unsigned type or that at least one, but not all of + * the bits was set in an signed type. + * Loss of significant bits means that it is not + * possible, also not with necessary casts, to convert + * back to the original type. A example for a + * necessary cast is: + * char c; int i; c = 128; + * i = c; ** yields -128 ** + * i = (unsigned char)c; ** yields 128 ** + */ + if (op == ASSIGN && tp->t_bitfield) { + /* precision lost in bit-field assignment */ + warning(166); + } else if (op == ASSIGN) { + /* constant truncated by assignment */ + warning(165); + } else if (op == INIT && tp->t_bitfield) { + /* bit-field initializer does not fit */ + warning(180); + } else if (op == INIT) { + /* initializer does not fit */ + warning(178); + } else if (op == CASE) { + /* case label affected by conversion */ + warning(196); + } else if (op == FARG) { + /* conv. of '%s' to '%s' is out of range, ... */ + warning(295, + type_name(gettyp(ot)), type_name(tp), arg); + } else { + /* conversion of '%s' to '%s' is out of range */ + warning(119, + type_name(gettyp(ot)), type_name(tp)); + } + } else if (nv->v_quad != v->v_quad) { + if (op == ASSIGN && tp->t_bitfield) { + /* precision lost in bit-field assignment */ + warning(166); + } else if (op == INIT && tp->t_bitfield) { + /* bit-field initializer out of range */ + warning(11); + } else if (op == CASE) { + /* case label affected by conversion */ + warning(196); + } else if (op == FARG) { + /* conv. of '%s' to '%s' is out of range, ... */ + warning(295, + type_name(gettyp(ot)), type_name(tp), arg); + } else { + /* conversion of '%s' to '%s' is out of range */ + warning(119, + type_name(gettyp(ot)), type_name(tp)); + } + } +} + /* * Converts a typed constant to a constant of another type. * @@ -2174,9 +2302,7 @@ convert_constant(op_t op, int arg, const { tspec_t ot, nt; int sz; - bool rchk; - int64_t xmask, xmsk1; - int osz, nsz; + bool range_check; /* * TODO: make 'v' const; the name of this function does not suggest @@ -2184,7 +2310,7 @@ convert_constant(op_t op, int arg, const */ ot = v->v_tspec; nt = nv->v_tspec = tp->t_tspec; - rchk = false; + range_check = false; if (nt == BOOL) { /* C99 6.3.1.2 */ nv->v_ansiu = false; @@ -2205,7 +2331,7 @@ convert_constant(op_t op, int arg, const nv->v_ldbl = (ot == PTR || is_uinteger(ot)) ? (ldbl_t)(uint64_t)v->v_quad : (ldbl_t)v->v_quad; } else { - rchk = true; /* Check for lost precision. */ + range_check = true; /* Check for lost precision. */ nv->v_quad = v->v_quad; } } @@ -2236,125 +2362,8 @@ convert_constant(op_t op, int arg, const break; } - if (rchk && op != CVT) { - 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]; - /* - * For bitwise operations we are not interested in the - * value, but in the bits itself. - */ - if (op == ORASS || op == BITOR || op == BITXOR) { - /* - * Print a warning if bits which were set are - * lost due to the conversion. - * This can happen with operator ORASS only. - */ - if (nsz < osz && (v->v_quad & xmask) != 0) { - /* constant truncated by conv., op %s */ - warning(306, op_name(op)); - } - } else if (op == ANDASS || op == BITAND) { - /* - * Print a warning if additional bits are not all 1 - * and the most significant bit of the old value is 1, - * or if at least one (but not all) removed bit was 0. - */ - if (nsz > osz && - (nv->v_quad & qbmasks[osz - 1]) != 0 && - (nv->v_quad & xmask) != xmask) { - /* extra bits set to 0 in conv. of '%s' ... */ - warning(309, type_name(gettyp(ot)), - type_name(tp), op_name(op)); - } else if (nsz < osz && - (v->v_quad & xmask) != xmask && - (v->v_quad & xmask) != 0) { - /* constant truncated by conv., op %s */ - warning(306, op_name(op)); - } - } else if ((nt != PTR && is_uinteger(nt)) && - (ot != PTR && !is_uinteger(ot)) && - v->v_quad < 0) { - if (op == ASSIGN) { - /* assignment of negative constant to ... */ - warning(164); - } else if (op == INIT) { - /* initialization of unsigned with neg... */ - warning(221); - } else if (op == FARG) { - /* conversion of negative constant to ... */ - warning(296, arg); - } else if (modtab[op].m_comparison) { - /* handled by check_integer_comparison() */ - } else { - /* conversion of negative constant to ... */ - warning(222); - } - } else if (nv->v_quad != v->v_quad && nsz <= osz && - (v->v_quad & xmask) != 0 && - (is_uinteger(ot) || (v->v_quad & xmsk1) != xmsk1)) { - /* - * Loss of significant bit(s). All truncated bits - * of unsigned types or all truncated bits plus the - * msb of the target for signed types are considered - * to be significant bits. Loss of significant bits - * means that at least on of the bits was set in an - * unsigned type or that at least one, but not all of - * the bits was set in an signed type. - * Loss of significant bits means that it is not - * possible, also not with necessary casts, to convert - * back to the original type. A example for a - * necessary cast is: - * char c; int i; c = 128; - * i = c; ** yields -128 ** - * i = (unsigned char)c; ** yields 128 ** - */ - if (op == ASSIGN && tp->t_bitfield) { - /* precision lost in bit-field assignment */ - warning(166); - } else if (op == ASSIGN) { - /* constant truncated by assignment */ - warning(165); - } else if (op == INIT && tp->t_bitfield) { - /* bit-field initializer does not fit */ - warning(180); - } else if (op == INIT) { - /* initializer does not fit */ - warning(178); - } else if (op == CASE) { - /* case label affected by conversion */ - warning(196); - } else if (op == FARG) { - /* conv. of '%s' to '%s' is out of range, ... */ - warning(295, - type_name(gettyp(ot)), type_name(tp), arg); - } else { - /* conversion of '%s' to '%s' is out of range */ - warning(119, - type_name(gettyp(ot)), type_name(tp)); - } - } else if (nv->v_quad != v->v_quad) { - if (op == ASSIGN && tp->t_bitfield) { - /* precision lost in bit-field assignment */ - warning(166); - } else if (op == INIT && tp->t_bitfield) { - /* bit-field initializer out of range */ - warning(11); - } else if (op == CASE) { - /* case label affected by conversion */ - warning(196); - } else if (op == FARG) { - /* conv. of '%s' to '%s' is out of range, ... */ - warning(295, - type_name(gettyp(ot)), type_name(tp), arg); - } else { - /* conversion of '%s' to '%s' is out of range */ - warning(119, - type_name(gettyp(ot)), type_name(tp)); - } - } - } + if (range_check && op != CVT) + convert_constant_check_range(ot, tp, nt, op, arg, v, nv); } /*