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);

Reply via email to