Module Name:    src
Committed By:   rillig
Date:           Sat Jan 28 00:24:05 UTC 2023

Modified Files:
        src/usr.bin/xlint/lint1: tree.c

Log Message:
lint: split integer promotions into separate functions

No functional change.


To generate a diff of this commit:
cvs rdiff -u -r1.495 -r1.496 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.495 src/usr.bin/xlint/lint1/tree.c:1.496
--- src/usr.bin/xlint/lint1/tree.c:1.495	Sat Jan 28 00:12:00 2023
+++ src/usr.bin/xlint/lint1/tree.c	Sat Jan 28 00:24:05 2023
@@ -1,4 +1,4 @@
-/*	$NetBSD: tree.c,v 1.495 2023/01/28 00:12:00 rillig Exp $	*/
+/*	$NetBSD: tree.c,v 1.496 2023/01/28 00:24:05 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.495 2023/01/28 00:12:00 rillig Exp $");
+__RCSID("$NetBSD: tree.c,v 1.496 2023/01/28 00:24:05 rillig Exp $");
 #endif
 
 #include <float.h>
@@ -2092,6 +2092,53 @@ new_tnode(op_t op, bool sys, type_t *typ
 	return ntn;
 }
 
+/* In traditional C, keep unsigned and promote FLOAT to DOUBLE. */
+static tspec_t
+promote_trad(tspec_t t)
+{
+
+	if (t == UCHAR || t == USHORT)
+		return UINT;
+	if (t == CHAR || t == SCHAR || t == SHORT)
+		return INT;
+	if (t == FLOAT)
+		return DOUBLE;
+	if (t == ENUM)
+		return INT;
+	return t;
+}
+
+/*
+ * C99 6.3.1.1p2 requires for types with lower rank than int that "If an int
+ * can represent all the values of the original type, the value is converted
+ * to an int; otherwise it is converted to an unsigned int", and that "All
+ * other types are unchanged by the integer promotions".
+ */
+static tspec_t
+promote_c90(const tnode_t *tn, tspec_t t, bool farg)
+{
+	if (tn->tn_type->t_bitfield) {
+		unsigned int len = tn->tn_type->t_flen;
+		if (len < size_in_bits(INT))
+			return INT;
+		if (len == size_in_bits(INT))
+			return is_uinteger(t) ? UINT : INT;
+		return t;
+	}
+
+	if (t == CHAR || t == UCHAR || t == SCHAR)
+		return size_in_bits(CHAR) < size_in_bits(INT) || t != UCHAR
+		    ? INT : UINT;
+	if (t == SHORT || t == USHORT)
+		return size_in_bits(SHORT) < size_in_bits(INT) || t == SHORT
+		    ? INT : UINT;
+	if (t == ENUM)
+		return INT;
+	if (farg && t == FLOAT)
+		return DOUBLE;
+	return t;
+}
+
 /*
  * Performs the "integer promotions" (C99 6.3.1.1p2), which convert small
  * integer types to either int or unsigned int.
@@ -2102,69 +2149,23 @@ new_tnode(op_t op, bool sys, type_t *typ
 tnode_t *
 promote(op_t op, bool farg, tnode_t *tn)
 {
-	tspec_t	t;
-	type_t	*ntp;
-	unsigned int len;
 
-	t = tn->tn_type->t_tspec;
-
-	if (!is_arithmetic(t))
+	tspec_t ot = tn->tn_type->t_tspec;
+	if (!is_arithmetic(ot))
 		return tn;
 
-	if (allow_c90) {
-		/*
-		 * C99 6.3.1.1p2 requires for types with lower rank than int
-		 * that "If an int can represent all the values of the
-		 * original type, the value is converted to an int; otherwise
-		 * it is converted to an unsigned int", and that "All other
-		 * types are unchanged by the integer promotions".
-		 */
-		if (tn->tn_type->t_bitfield) {
-			len = tn->tn_type->t_flen;
-			if (len < size_in_bits(INT)) {
-				t = INT;
-			} else if (len == size_in_bits(INT)) {
-				t = is_uinteger(t) ? UINT : INT;
-			}
-		} else if (t == CHAR || t == UCHAR || t == SCHAR) {
-			t = (size_in_bits(CHAR) < size_in_bits(INT)
-			     || t != UCHAR) ? INT : UINT;
-		} else if (t == SHORT || t == USHORT) {
-			t = (size_in_bits(SHORT) < size_in_bits(INT)
-			     || t == SHORT) ? INT : UINT;
-		} else if (t == ENUM) {
-			t = INT;
-		} else if (farg && t == FLOAT) {
-			t = DOUBLE;
-		}
-	} else {
-		/*
-		 * In traditional C, keep unsigned and promote FLOAT
-		 * to DOUBLE.
-		 */
-		if (t == UCHAR || t == USHORT) {
-			t = UINT;
-		} else if (t == CHAR || t == SCHAR || t == SHORT) {
-			t = INT;
-		} else if (t == FLOAT) {
-			t = DOUBLE;
-		} else if (t == ENUM) {
-			t = INT;
-		}
-	}
-
-	if (t != tn->tn_type->t_tspec) {
-		ntp = expr_dup_type(tn->tn_type);
-		ntp->t_tspec = t;
-		/*
-		 * Keep t_is_enum even though t_tspec gets converted from
-		 * ENUM to INT, so we are later able to check compatibility
-		 * of enum types.
-		 */
-		tn = convert(op, 0, ntp, tn);
-	}
+	tspec_t nt = allow_c90 ? promote_c90(tn, ot, farg) : promote_trad(ot);
+	if (nt == ot)
+		return tn;
 
-	return tn;
+	type_t *ntp = expr_dup_type(tn->tn_type);
+	ntp->t_tspec = nt;
+	/*
+	 * Keep t_is_enum even though t_tspec gets converted from
+	 * ENUM to INT, so we are later able to check compatibility
+	 * of enum types.
+	 */
+	return convert(op, 0, ntp, tn);
 }
 
 static tnode_t *

Reply via email to