Module Name:    src
Committed By:   rillig
Date:           Sun Jan 22 16:05:08 UTC 2023

Modified Files:
        src/tests/usr.bin/xlint/lint1: msg_071.c msg_075.c
        src/usr.bin/xlint/lint1: lex.c tree.c

Log Message:
lint: prevent undefined behavior for signed '<<'

Found by manual code inspection, verified by MKSANITIZER=yes
USE_SANITIZER=undefined.


To generate a diff of this commit:
cvs rdiff -u -r1.5 -r1.6 src/tests/usr.bin/xlint/lint1/msg_071.c
cvs rdiff -u -r1.4 -r1.5 src/tests/usr.bin/xlint/lint1/msg_075.c
cvs rdiff -u -r1.144 -r1.145 src/usr.bin/xlint/lint1/lex.c
cvs rdiff -u -r1.493 -r1.494 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/tests/usr.bin/xlint/lint1/msg_071.c
diff -u src/tests/usr.bin/xlint/lint1/msg_071.c:1.5 src/tests/usr.bin/xlint/lint1/msg_071.c:1.6
--- src/tests/usr.bin/xlint/lint1/msg_071.c:1.5	Wed Jun 15 20:18:31 2022
+++ src/tests/usr.bin/xlint/lint1/msg_071.c	Sun Jan 22 16:05:08 2023
@@ -1,9 +1,16 @@
-/*	$NetBSD: msg_071.c,v 1.5 2022/06/15 20:18:31 rillig Exp $	*/
+/*	$NetBSD: msg_071.c,v 1.6 2023/01/22 16:05:08 rillig Exp $	*/
 # 3 "msg_071.c"
 
 // Test for message: too many characters in character constant [71]
 
 /*
+ * See also:
+ *	lex_char.c
+ *	lex_char_uchar.c
+ *	lex_wide_char.c
+ */
+
+/*
  * C11 6.4.4.4p7 says: Each hexadecimal escape sequence is the longest
  * sequence of characters that can constitute the escape sequence.
  */

Index: src/tests/usr.bin/xlint/lint1/msg_075.c
diff -u src/tests/usr.bin/xlint/lint1/msg_075.c:1.4 src/tests/usr.bin/xlint/lint1/msg_075.c:1.5
--- src/tests/usr.bin/xlint/lint1/msg_075.c:1.4	Wed Jun 15 20:18:31 2022
+++ src/tests/usr.bin/xlint/lint1/msg_075.c	Sun Jan 22 16:05:08 2023
@@ -1,7 +1,19 @@
-/*	$NetBSD: msg_075.c,v 1.4 2022/06/15 20:18:31 rillig Exp $	*/
+/*	$NetBSD: msg_075.c,v 1.5 2023/01/22 16:05:08 rillig Exp $	*/
 # 3 "msg_075.c"
 
 // Test for message: overflow in hex escape [75]
 
+/*
+ * See also:
+ *	lex_char.c
+ *	lex_char_uchar.c
+ *	lex_string.c
+ *	lex_wide_char.c
+ *	lex_wide_string.c
+ */
+
 /* expect+1: warning: overflow in hex escape [75] */
 char str[] = "\x12345678123456781234567812345678";
+
+/* C11 6.4.4.4p7 */
+char leading_zeroes = '\x0000000000000000000000000000020';

Index: src/usr.bin/xlint/lint1/lex.c
diff -u src/usr.bin/xlint/lint1/lex.c:1.144 src/usr.bin/xlint/lint1/lex.c:1.145
--- src/usr.bin/xlint/lint1/lex.c:1.144	Sat Jan 21 21:26:40 2023
+++ src/usr.bin/xlint/lint1/lex.c	Sun Jan 22 16:05:08 2023
@@ -1,4 +1,4 @@
-/* $NetBSD: lex.c,v 1.144 2023/01/21 21:26:40 rillig Exp $ */
+/* $NetBSD: lex.c,v 1.145 2023/01/22 16:05:08 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.144 2023/01/21 21:26:40 rillig Exp $");
+__RCSID("$NetBSD: lex.c,v 1.145 2023/01/22 16:05:08 rillig Exp $");
 #endif
 
 #include <ctype.h>
@@ -751,13 +751,13 @@ read_escaped_oct(int c)
 	return value;
 }
 
-static int
+static unsigned int
 read_escaped_hex(int c)
 {
 	if (!allow_c90)
 		/* \x undefined in traditional C */
 		warning(82);
-	int value = 0;
+	unsigned int value = 0;
 	int state = 0;		/* 0 = no digits, 1 = OK, 2 = overflow */
 	while (c = read_byte(), isxdigit(c)) {
 		c = isdigit(c) ? c - '0' : toupper(c) - 'A' + 10;
@@ -830,7 +830,7 @@ read_escaped_backslash(int delim)
 	case '4': case '5': case '6': case '7':
 		return read_escaped_oct(c);
 	case 'x':
-		return read_escaped_hex(c);
+		return (int)read_escaped_hex(c);
 	case '\n':
 		return -3;
 	case EOF:
@@ -902,15 +902,17 @@ lex_character_constant(void)
 	n = 0;
 	val = 0;
 	while ((c = get_escaped_char('\'')) >= 0) {
-		val = (val << CHAR_SIZE) + c;
+		val = (int)((unsigned int)val << CHAR_SIZE) + c;
 		n++;
 	}
 	if (c == -2) {
 		/* unterminated character constant */
 		error(253);
 	} else if (n > sizeof(int) || (n > 1 && (pflag || hflag))) {
-		/* XXX: should rather be sizeof(TARG_INT) */
-
+		/*
+		 * XXX: ^^ should rather be sizeof(TARG_INT). Luckily,
+		 * sizeof(int) is the same on all supported platforms.
+		 */
 		/* too many characters in character constant */
 		error(71);
 	} else if (n > 1) {

Index: src/usr.bin/xlint/lint1/tree.c
diff -u src/usr.bin/xlint/lint1/tree.c:1.493 src/usr.bin/xlint/lint1/tree.c:1.494
--- src/usr.bin/xlint/lint1/tree.c:1.493	Sat Jan 21 20:07:01 2023
+++ src/usr.bin/xlint/lint1/tree.c	Sun Jan 22 16:05:08 2023
@@ -1,4 +1,4 @@
-/*	$NetBSD: tree.c,v 1.493 2023/01/21 20:07:01 rillig Exp $	*/
+/*	$NetBSD: tree.c,v 1.494 2023/01/22 16:05:08 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.493 2023/01/21 20:07:01 rillig Exp $");
+__RCSID("$NetBSD: tree.c,v 1.494 2023/01/22 16:05:08 rillig Exp $");
 #endif
 
 #include <float.h>
@@ -3609,6 +3609,7 @@ fold(tnode_t *tn)
 		break;
 	case SHL:
 		/* TODO: warn about out-of-bounds 'sr'. */
+		/* TODO: warn about overflow in signed '<<'. */
 		q = utyp ? (int64_t)(ul << (sr & 63)) : sl << (sr & 63);
 		break;
 	case SHR:

Reply via email to