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