Module Name:    src
Committed By:   rillig
Date:           Sat Jan 27 12:14:58 UTC 2024

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

Log Message:
lint: extract signedness detection from lexing an integer constant

An integer constant that is signed in traditional C but unsigned since
C90 is an edge case that should not clutter the main code of determining
the resulting type of the constant.

The code for lexing an integer constant doesn't implement the C99 rules
yet, which convert a constant to the 'long long' types if the 'long'
types don't suffice.


To generate a diff of this commit:
cvs rdiff -u -r1.200 -r1.201 src/usr.bin/xlint/lint1/lex.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/lex.c
diff -u src/usr.bin/xlint/lint1/lex.c:1.200 src/usr.bin/xlint/lint1/lex.c:1.201
--- src/usr.bin/xlint/lint1/lex.c:1.200	Tue Jan 23 19:44:28 2024
+++ src/usr.bin/xlint/lint1/lex.c	Sat Jan 27 12:14:58 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: lex.c,v 1.200 2024/01/23 19:44:28 rillig Exp $ */
+/* $NetBSD: lex.c,v 1.201 2024/01/27 12:14:58 rillig Exp $ */
 
 /*
  * Copyright (c) 1996 Christopher G. Demetriou.  All Rights Reserved.
@@ -38,7 +38,7 @@
 
 #include <sys/cdefs.h>
 #if defined(__RCSID)
-__RCSID("$NetBSD: lex.c,v 1.200 2024/01/23 19:44:28 rillig Exp $");
+__RCSID("$NetBSD: lex.c,v 1.201 2024/01/27 12:14:58 rillig Exp $");
 #endif
 
 #include <ctype.h>
@@ -487,6 +487,21 @@ lex_name(const char *yytext, size_t yyle
 	return T_NAME;
 }
 
+// Determines whether the constant is signed in traditional C but unsigned in
+// C90 and later.
+static bool
+is_unsigned_since_c90(tspec_t typ, uint64_t ui, int base)
+{
+	if (!(allow_trad && allow_c90))
+		return false;
+	if (typ == INT) {
+		if (ui > TARG_INT_MAX && ui <= TARG_UINT_MAX && base != 10)
+			return true;
+		return ui > TARG_LONG_MAX;
+	}
+	return typ == LONG && ui > TARG_LONG_MAX;
+}
+
 int
 lex_integer_constant(const char *yytext, size_t yyleng, int base)
 {
@@ -546,11 +561,7 @@ lex_integer_constant(const char *yytext,
 		query_message(8, (int)len, cp);
 	}
 
-	/*
-	 * If the value is too big for the current type, we must choose another
-	 * type.
-	 */
-	bool ansiu = false;
+	bool ansiu = is_unsigned_since_c90(typ, ui, base);
 	switch (typ) {
 	case INT:
 		if (ui <= TARG_INT_MAX) {
@@ -566,17 +577,8 @@ lex_integer_constant(const char *yytext,
 				warning(252);
 			}
 		}
-		if (typ == UINT || typ == ULONG) {
-			if (!allow_c90) {
-				typ = LONG;
-			} else if (allow_trad) {
-				/*
-				 * Remember that the constant is unsigned only
-				 * in C90.
-				 */
-				ansiu = true;
-			}
-		}
+		if ((typ == UINT || typ == ULONG) && !allow_c90)
+			typ = LONG;
 		break;
 	case UINT:
 		if (ui > TARG_UINT_MAX) {
@@ -590,8 +592,6 @@ lex_integer_constant(const char *yytext,
 	case LONG:
 		if (ui > TARG_LONG_MAX && allow_c90) {
 			typ = ULONG;
-			if (allow_trad)
-				ansiu = true;
 			if (ui > TARG_ULONG_MAX && !warned) {
 				/* integer constant out of range */
 				warning(252);

Reply via email to