Module Name:    src
Committed By:   rillig
Date:           Sat Sep  4 21:20:44 UTC 2021

Modified Files:
        src/tests/usr.bin/xlint/lint1: msg_117.c msg_117.exp

Log Message:
tests/lint: provide more background information on signed '>>'


To generate a diff of this commit:
cvs rdiff -u -r1.9 -r1.10 src/tests/usr.bin/xlint/lint1/msg_117.c
cvs rdiff -u -r1.8 -r1.9 src/tests/usr.bin/xlint/lint1/msg_117.exp

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_117.c
diff -u src/tests/usr.bin/xlint/lint1/msg_117.c:1.9 src/tests/usr.bin/xlint/lint1/msg_117.c:1.10
--- src/tests/usr.bin/xlint/lint1/msg_117.c:1.9	Fri Aug 27 17:59:46 2021
+++ src/tests/usr.bin/xlint/lint1/msg_117.c	Sat Sep  4 21:20:44 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: msg_117.c,v 1.9 2021/08/27 17:59:46 rillig Exp $	*/
+/*	$NetBSD: msg_117.c,v 1.10 2021/09/04 21:20:44 rillig Exp $	*/
 # 3 "msg_117.c"
 
 // Test for message: bitwise '%s' on signed value possibly nonportable [117]
@@ -66,3 +66,70 @@ shr_unsigned_char_promoted_unsigned(unsi
 	 */
 	return (unsigned char)((unsigned char)(bit - 1) >> 5);
 }
+
+/*
+ * C90 3.3.7, C99 6.5.7 and C11 6.5.7 all say the same: If E1 has a signed
+ * type and a negative value, the resulting value is implementation-defined.
+ *
+ * These standards don't guarantee anything about the lower bits of the
+ * resulting value, which are generally independent of whether the shift is
+ * performed in signed arithmetics or in unsigned arithmetics.  The C99
+ * rationale talks about signed shifts, but does not provide any guarantee
+ * either.  It merely suggests that platforms are free to use unsigned shifts
+ * even if the operand type is signed.
+ *
+ * K&R provides more guarantees by saying: Right shifting a signed quantity
+ * will fill with sign bits ("arithmetic shift") on some machines such as the
+ * PDP-Il, and with 0-bits ("logical shift") on others.
+ *
+ * https://gcc.gnu.org/onlinedocs/gcc/Integers-implementation.html says:
+ * Signed '>>' acts on negative numbers by sign extension.
+ *
+ * This means that at least in GCC mode, lint may decide to not warn about
+ * these cases.
+ */
+void
+shr_signed_ignoring_high_bits(int x)
+{
+
+	/*
+	 * All sane platforms should define that 'x >> 0 == x', even if x is
+	 * negative.
+	 */
+	/* expect+1: warning: bitwise '>>' on signed value possibly nonportable [117] */
+	if (x >> 0 != 0)
+		return;
+
+	/*
+	 * If x is negative, x >> 1 is nonzero, no matter whether the shift
+	 * is arithmetic or logical.
+	 */
+	/* expect+1: warning: bitwise '>>' on signed value possibly nonportable [117] */
+	if (x >> 1 != 0)
+		return;
+
+	/*
+	 * The highest bit may be 0 or 1, the others should be well-defined
+	 * on all sane platforms, making it irrelevant whether the actual
+	 * shift operation is arithmetic or logical.
+	 */
+	/* expect+1: warning: bitwise '>>' on signed value possibly nonportable [117] */
+	if (((x >> 1) & 1) != 0)
+		return;
+
+	/*
+	 * The result of this expression is the same with arithmetic and
+	 * logical shifts since the filled bits are masked out.
+	 */
+	/* expect+1: warning: bitwise '>>' on signed value possibly nonportable [117] */
+	if (((x >> 31) & 1) != 0)
+		return;
+
+	/*
+	 * In this case, arithmetic shift results in 2 while logical shift
+	 * results in 0.  This difference is what this warning is about.
+	 */
+	/* expect+1: warning: bitwise '>>' on signed value possibly nonportable [117] */
+	if (((x >> 31) & 2) != 0)
+		return;
+}

Index: src/tests/usr.bin/xlint/lint1/msg_117.exp
diff -u src/tests/usr.bin/xlint/lint1/msg_117.exp:1.8 src/tests/usr.bin/xlint/lint1/msg_117.exp:1.9
--- src/tests/usr.bin/xlint/lint1/msg_117.exp:1.8	Fri Aug 27 17:59:46 2021
+++ src/tests/usr.bin/xlint/lint1/msg_117.exp	Sat Sep  4 21:20:44 2021
@@ -5,3 +5,8 @@ msg_117.c(29): warning: shift amount 466
 msg_117.c(35): warning: bitwise '>>' on signed value possibly nonportable [117]
 msg_117.c(35): warning: negative shift [121]
 msg_117.c(57): warning: bitwise '>>' on signed value possibly nonportable [117]
+msg_117.c(100): warning: bitwise '>>' on signed value possibly nonportable [117]
+msg_117.c(108): warning: bitwise '>>' on signed value possibly nonportable [117]
+msg_117.c(117): warning: bitwise '>>' on signed value possibly nonportable [117]
+msg_117.c(125): warning: bitwise '>>' on signed value possibly nonportable [117]
+msg_117.c(133): warning: bitwise '>>' on signed value possibly nonportable [117]

Reply via email to