Module Name: src Committed By: rillig Date: Sat Jan 28 00:39:49 UTC 2023
Modified Files: src/usr.bin/xlint/lint1: tree.c Log Message: lint: split usual arithmetic conversions into separate functions No functional change. To generate a diff of this commit: cvs rdiff -u -r1.496 -r1.497 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.496 src/usr.bin/xlint/lint1/tree.c:1.497 --- src/usr.bin/xlint/lint1/tree.c:1.496 Sat Jan 28 00:24:05 2023 +++ src/usr.bin/xlint/lint1/tree.c Sat Jan 28 00:39:49 2023 @@ -1,4 +1,4 @@ -/* $NetBSD: tree.c,v 1.496 2023/01/28 00:24:05 rillig Exp $ */ +/* $NetBSD: tree.c,v 1.497 2023/01/28 00:39:49 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.496 2023/01/28 00:24:05 rillig Exp $"); +__RCSID("$NetBSD: tree.c,v 1.497 2023/01/28 00:39:49 rillig Exp $"); #endif #include <float.h> @@ -2181,81 +2181,88 @@ apply_usual_arithmetic_conversions(op_t return convert(op, 0, ntp, tn); } +static const tspec_t arith_rank[] = { + LDOUBLE, DOUBLE, FLOAT, +#ifdef INT128_SIZE + UINT128, INT128, +#endif + UQUAD, QUAD, + ULONG, LONG, + UINT, INT, +}; + +/* Keep unsigned in traditional C */ +static tspec_t +usual_arithmetic_conversion_trad(tspec_t lt, tspec_t rt) +{ + + bool u = is_uinteger(lt) || is_uinteger(rt); + size_t i; + for (i = 0; arith_rank[i] != INT; i++) + if (lt == arith_rank[i] || rt == arith_rank[i]) + break; + + tspec_t t = arith_rank[i]; + if (u && is_integer(t) && !is_uinteger(t)) + return unsigned_type(t); + return t; +} + +static tspec_t +usual_arithmetic_conversion_c90(tspec_t lt, tspec_t rt) +{ + + if (lt == rt) + return lt; + + if (lt == LCOMPLEX || rt == LCOMPLEX) + return LCOMPLEX; + if (lt == DCOMPLEX || rt == DCOMPLEX) + return DCOMPLEX; + if (lt == FCOMPLEX || rt == FCOMPLEX) + return FCOMPLEX; + if (lt == LDOUBLE || rt == LDOUBLE) + return LDOUBLE; + if (lt == DOUBLE || rt == DOUBLE) + return DOUBLE; + if (lt == FLOAT || rt == FLOAT) + return FLOAT; + + /* + * If type A has more bits than type B, it should be able to hold all + * possible values of type B. + */ + if (size_in_bits(lt) > size_in_bits(rt)) + return lt; + if (size_in_bits(lt) < size_in_bits(rt)) + return rt; + + size_t i; + for (i = 3; arith_rank[i] != INT; i++) + if (arith_rank[i] == lt || arith_rank[i] == rt) + break; + if ((is_uinteger(lt) || is_uinteger(rt)) && + !is_uinteger(arith_rank[i])) + i--; + return arith_rank[i]; +} + /* - * Apply the "usual arithmetic conversions" (C99 6.3.1.8). - * - * This gives both operands the same type. - * This is done in different ways for traditional C and C90. + * Apply the "usual arithmetic conversions" (C99 6.3.1.8), which gives both + * operands the same type. */ static void balance(op_t op, tnode_t **lnp, tnode_t **rnp) { - tspec_t lt, rt, t; - int i; - bool u; - static const tspec_t tl[] = { - LDOUBLE, DOUBLE, FLOAT, -#ifdef INT128_SIZE - UINT128, INT128, -#endif - UQUAD, QUAD, - ULONG, LONG, - UINT, INT, - }; - - lt = (*lnp)->tn_type->t_tspec; - rt = (*rnp)->tn_type->t_tspec; + tspec_t lt = (*lnp)->tn_type->t_tspec; + tspec_t rt = (*rnp)->tn_type->t_tspec; if (!is_arithmetic(lt) || !is_arithmetic(rt)) return; - if (allow_c90) { - if (lt == rt) { - t = lt; - } else if (lt == LCOMPLEX || rt == LCOMPLEX) { - t = LCOMPLEX; - } else if (lt == DCOMPLEX || rt == DCOMPLEX) { - t = DCOMPLEX; - } else if (lt == FCOMPLEX || rt == FCOMPLEX) { - t = FCOMPLEX; - } else if (lt == LDOUBLE || rt == LDOUBLE) { - t = LDOUBLE; - } else if (lt == DOUBLE || rt == DOUBLE) { - t = DOUBLE; - } else if (lt == FLOAT || rt == FLOAT) { - t = FLOAT; - } else { - /* - * If type A has more bits than type B it should - * be able to hold all possible values of type B. - */ - if (size_in_bits(lt) > size_in_bits(rt)) { - t = lt; - } else if (size_in_bits(lt) < size_in_bits(rt)) { - t = rt; - } else { - for (i = 3; tl[i] != INT; i++) { - if (tl[i] == lt || tl[i] == rt) - break; - } - if ((is_uinteger(lt) || is_uinteger(rt)) && - !is_uinteger(tl[i])) { - i--; - } - t = tl[i]; - } - } - } else { - /* Keep unsigned in traditional C */ - u = is_uinteger(lt) || is_uinteger(rt); - for (i = 0; tl[i] != INT; i++) { - if (lt == tl[i] || rt == tl[i]) - break; - } - t = tl[i]; - if (u && is_integer(t) && !is_uinteger(t)) - t = unsigned_type(t); - } + tspec_t t = allow_c90 + ? usual_arithmetic_conversion_c90(lt, rt) + : usual_arithmetic_conversion_trad(lt, rt); if (t != lt) *lnp = apply_usual_arithmetic_conversions(op, *lnp, t);