Module Name:    src
Committed By:   rillig
Date:           Thu Aug 19 20:32:33 UTC 2021

Modified Files:
        src/distrib/sets/lists/tests: mi
        src/tests/usr.bin/xlint: check-expect.lua
        src/tests/usr.bin/xlint/lint1: Makefile
Added Files:
        src/tests/usr.bin/xlint/lint1: expr_fold.c expr_fold.exp

Log Message:
tests/lint: test folding of constant expressions

Since November 2001, there is a comment above the function 'fold' that
suggests there are a few bugs concerning overflow detection.  Add some
first 'proper regression tests' to prove these bugs.


To generate a diff of this commit:
cvs rdiff -u -r1.1112 -r1.1113 src/distrib/sets/lists/tests/mi
cvs rdiff -u -r1.10 -r1.11 src/tests/usr.bin/xlint/check-expect.lua
cvs rdiff -u -r1.104 -r1.105 src/tests/usr.bin/xlint/lint1/Makefile
cvs rdiff -u -r0 -r1.1 src/tests/usr.bin/xlint/lint1/expr_fold.c \
    src/tests/usr.bin/xlint/lint1/expr_fold.exp

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/distrib/sets/lists/tests/mi
diff -u src/distrib/sets/lists/tests/mi:1.1112 src/distrib/sets/lists/tests/mi:1.1113
--- src/distrib/sets/lists/tests/mi:1.1112	Mon Aug 16 20:11:03 2021
+++ src/distrib/sets/lists/tests/mi	Thu Aug 19 20:32:33 2021
@@ -1,4 +1,4 @@
-# $NetBSD: mi,v 1.1112 2021/08/16 20:11:03 rillig Exp $
+# $NetBSD: mi,v 1.1113 2021/08/19 20:32:33 rillig Exp $
 #
 # Note: don't delete entries from here - mark them as "obsolete" instead.
 #
@@ -6247,6 +6247,8 @@
 ./usr/tests/usr.bin/xlint/lint1/expr_binary_trad.exp		tests-usr.bin-tests	compattestfile,atf
 ./usr/tests/usr.bin/xlint/lint1/expr_cast.c			tests-usr.bin-tests	compattestfile,atf
 ./usr/tests/usr.bin/xlint/lint1/expr_cast.exp			tests-usr.bin-tests	compattestfile,atf
+./usr/tests/usr.bin/xlint/lint1/expr_fold.c			tests-usr.bin-tests	compattestfile,atf
+./usr/tests/usr.bin/xlint/lint1/expr_fold.exp			tests-usr.bin-tests	compattestfile,atf
 ./usr/tests/usr.bin/xlint/lint1/expr_precedence.c		tests-usr.bin-tests	compattestfile,atf
 ./usr/tests/usr.bin/xlint/lint1/expr_precedence.exp		tests-usr.bin-tests	compattestfile,atf
 ./usr/tests/usr.bin/xlint/lint1/expr_promote.c			tests-usr.bin-tests	compattestfile,atf

Index: src/tests/usr.bin/xlint/check-expect.lua
diff -u src/tests/usr.bin/xlint/check-expect.lua:1.10 src/tests/usr.bin/xlint/check-expect.lua:1.11
--- src/tests/usr.bin/xlint/check-expect.lua:1.10	Mon Jul  5 19:02:14 2021
+++ src/tests/usr.bin/xlint/check-expect.lua	Thu Aug 19 20:32:33 2021
@@ -1,5 +1,5 @@
 #!  /usr/bin/lua
--- $NetBSD: check-expect.lua,v 1.10 2021/07/05 19:02:14 rillig Exp $
+-- $NetBSD: check-expect.lua,v 1.11 2021/08/19 20:32:33 rillig Exp $
 
 --[[
 
@@ -116,7 +116,7 @@ local function check_test(c_fname, error
     end
 
     if not found then
-      errors:add("error: %s: must expect \"%s\"", act.location, act.message)
+      errors:add("error: %s: missing /* expect: %s */", act.location, act.message)
     end
   end
 

Index: src/tests/usr.bin/xlint/lint1/Makefile
diff -u src/tests/usr.bin/xlint/lint1/Makefile:1.104 src/tests/usr.bin/xlint/lint1/Makefile:1.105
--- src/tests/usr.bin/xlint/lint1/Makefile:1.104	Mon Aug 16 20:11:03 2021
+++ src/tests/usr.bin/xlint/lint1/Makefile	Thu Aug 19 20:32:33 2021
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile,v 1.104 2021/08/16 20:11:03 rillig Exp $
+# $NetBSD: Makefile,v 1.105 2021/08/19 20:32:33 rillig Exp $
 
 NOMAN=		# defined
 MAX_MESSAGE=	346		# see lint1/err.c
@@ -139,6 +139,8 @@ FILES+=		expr_binary_trad.c
 FILES+=		expr_binary_trad.exp
 FILES+=		expr_cast.c
 FILES+=		expr_cast.exp
+FILES+=		expr_fold.c
+FILES+=		expr_fold.exp
 FILES+=		expr_precedence.c
 FILES+=		expr_precedence.exp
 FILES+=		expr_promote.c

Added files:

Index: src/tests/usr.bin/xlint/lint1/expr_fold.c
diff -u /dev/null src/tests/usr.bin/xlint/lint1/expr_fold.c:1.1
--- /dev/null	Thu Aug 19 20:32:33 2021
+++ src/tests/usr.bin/xlint/lint1/expr_fold.c	Thu Aug 19 20:32:33 2021
@@ -0,0 +1,287 @@
+/*	$NetBSD: expr_fold.c,v 1.1 2021/08/19 20:32:33 rillig Exp $	*/
+# 3 "expr_fold.c"
+
+/*
+ * Test folding of constant expressions.
+ */
+
+/* lint1-extra-flags: -h */
+
+/*
+ * On ILP32 platforms, the integer constant 2147483648 cannot be represented
+ * as 'int' or 'long', therefore it becomes 'long long'.  This would
+ * influence the type names in the diagnostics.
+ */
+/* lint1-only-if: lp64 */
+
+void take_bool(_Bool);
+void take_int(int);
+void take_uint(unsigned int);
+
+/*
+ * C99 6.4.4.1p5 defines that decimal integer constants without suffix get
+ * one of the signed integer types. On the other hand, octal and hexadecimal
+ * constants get either a signed or unsigned type, whichever fits first.
+ */
+
+void
+fold_uplus(void)
+{
+	take_int(+(0));
+	take_int(+(2147483647));
+	/* XXX: one of these two messages is redundant */
+	/* expect+2: warning: argument #1 is converted from 'long' to 'int' due to prototype [259] */
+	/* expect+1: warning: conversion of 'long' to 'int' is out of range, arg #1 [295] */
+	take_int(+(2147483648));
+	/* XXX: one of these two messages is redundant */
+	/* expect+2: warning: argument #1 is converted from 'long' to 'int' due to prototype [259] */
+	/* expect+1: warning: conversion of 'long' to 'int' is out of range, arg #1 [295] */
+	take_int(+(4294967295));
+
+	take_uint(+(0));
+	take_uint(+(2147483647));
+	/* expect+1: warning: argument #1 is converted from 'long' to 'unsigned int' due to prototype [259] */
+	take_uint(+(2147483648));
+	/* expect+1: warning: argument #1 is converted from 'long' to 'unsigned int' due to prototype [259] */
+	take_uint(+(4294967295));
+
+	/*
+	 * Hexadecimal constants and constants with the suffix 'U' get either
+	 * a signed or an unsigned integer type, so no warning here.
+	 */
+	take_uint(+(2147483648U));
+	take_uint(+(0x80000000));
+	take_uint(+(0x80000000U));
+}
+
+void
+fold_uminus(void)
+{
+	take_int(-(0));
+	take_int(-(2147483647));
+
+	/* expect+1: warning: argument #1 is converted from 'long' to 'int' due to prototype [259] */
+	take_int(-(2147483648));
+
+	/* The '-' is an operator, it is not part of the integer constant. */
+	/* expect+1: warning: argument #1 is converted from 'long' to 'int' due to prototype [259] */
+	take_int(-2147483648);
+
+	/* expect+2: warning: integer overflow detected, op + [141] */
+	/* expect+1: warning: integer overflow detected, op - [141] */
+	take_int(-(2147483647 + 1));
+	/* expect+1: warning: integer overflow detected, op - [141] */
+	take_int(-(-2147483647 - 1));
+	/* expect+2: warning: argument #1 is converted from 'long' to 'int' due to prototype [259] */
+	/* expect+1: warning: conversion of 'long' to 'int' is out of range, arg #1 [295] */
+	take_int(-(4294967295));
+
+	take_uint(-(0));
+	/* expect+2: warning: conversion of negative constant to unsigned type, arg #1 [296] */
+	/* expect+1: warning: argument #1 is converted from 'int' to 'unsigned int' due to prototype [259] */
+	take_uint(-(2147483647));
+	/* expect+2: warning: argument #1 is converted from 'long' to 'unsigned int' due to prototype [259] */
+	/* expect+1: warning: conversion of negative constant to unsigned type, arg #1 [296] */
+	take_uint(-(2147483648));
+	/* expect+2: warning: argument #1 is converted from 'long' to 'unsigned int' due to prototype [259] */
+	/* expect+1: warning: conversion of negative constant to unsigned type, arg #1 [296] */
+	take_uint(-(4294967295));
+}
+
+void
+fold_compl(void)
+{
+	take_int(~(0));
+	take_int(~(2147483647));
+	/* expect+2: warning: argument #1 is converted from 'long' to 'int' due to prototype [259] */
+	/* expect+1: warning: conversion of 'long' to 'int' is out of range, arg #1 [295] */
+	take_int(~(2147483648));
+	/* expect+2: warning: argument #1 is converted from 'long' to 'int' due to prototype [259] */
+	/* expect+1: warning: conversion of 'long' to 'int' is out of range, arg #1 [295] */
+	take_int(~(4294967295));
+
+	/* expect+2: warning: conversion of negative constant to unsigned type, arg #1 [296] */
+	/* expect+1: warning: argument #1 is converted from 'int' to 'unsigned int' due to prototype [259] */
+	take_uint(~(0));
+	/* expect+2: warning: argument #1 is converted from 'int' to 'unsigned int' due to prototype [259] */
+	/* expect+1: warning: conversion of negative constant to unsigned type, arg #1 [296] */
+	take_uint(~(2147483647));
+	/* expect+2: warning: argument #1 is converted from 'long' to 'unsigned int' due to prototype [259] */
+	/* expect+1: warning: conversion of negative constant to unsigned type, arg #1 [296] */
+	take_uint(~(2147483648));
+	/* expect+2: warning: argument #1 is converted from 'long' to 'unsigned int' due to prototype [259] */
+	/* expect+1: warning: conversion of negative constant to unsigned type, arg #1 [296] */
+	take_uint(~(4294967295));
+}
+
+void
+fold_mult(void)
+{
+	take_int(32767 * 65536);
+	/* expect+1: warning: integer overflow detected, op * [141] */
+	take_int(32768 * 65536);
+	/* expect+1: warning: integer overflow detected, op * [141] */
+	take_int(65536 * 65536);
+
+	take_uint(32767 * 65536U);
+	take_uint(32768 * 65536U);
+	/* expect+1: warning: integer overflow detected, op * [141] */
+	take_uint(65536 * 65536U);
+}
+
+void
+fold_div(void)
+{
+	/* expect+3: error: division by 0 [139] */
+	/* XXX: The following message is redundant. */
+	/* expect+1: warning: integer overflow detected, op / [141] */
+	take_int(0 / 0);
+
+	/* expect+2: warning: argument #1 is converted from 'long' to 'int' due to prototype [259] */
+	/* expect+1: warning: conversion of 'long' to 'int' is out of range, arg #1 [295] */
+	take_int(-2147483648 / -1);
+}
+
+void
+fold_mod(void)
+{
+	/* expect+1: error: modulus by 0 [140] */
+	take_int(0 % 0);
+	/* expect+1: error: modulus by 0 [140] */
+	take_int(0 % 0U);
+	/* expect+1: error: modulus by 0 [140] */
+	take_int(0U % 0);
+	/* expect+1: error: modulus by 0 [140] */
+	take_int(0U % 0U);
+
+	/* expect+1: warning: argument #1 is converted from 'long' to 'int' due to prototype [259] */
+	take_int(-2147483648 % -1);
+}
+
+void
+fold_plus(void)
+{
+	/* expect+1: warning: integer overflow detected, op + [141] */
+	take_int(2147483647 + 1);
+
+	/* Assume two's complement, so no overflow. */
+	take_int(-2147483647 + -1);
+
+	/* expect+1: warning: integer overflow detected, op + [141] */
+	take_int(-2147483647 + -2);
+
+	/*
+	 * No overflow since one of the operands is unsigned, therefore the
+	 * other operand is converted to unsigned as well.
+	 * See C99 6.3.1.8p1, paragraph 8 of 10.
+	 */
+	/*FIXME*//* expect+1: warning: integer overflow detected, op + [141] */
+	take_uint(2147483647 + 1U);
+	/*FIXME*//* expect+1: warning: integer overflow detected, op + [141] */
+	take_uint(2147483647U + 1);
+}
+
+void
+fold_minus(void)
+{
+	/* expect+1: warning: integer overflow detected, op - [141] */
+	take_int(2147483647 - -1);
+	/* Assume two's complement. */
+	take_int(-2147483647 - 1);
+	/* expect+1: warning: integer overflow detected, op - [141] */
+	take_int(-2147483647 - 2);
+
+	/* expect+1: warning: argument #1 is converted from 'long' to 'int' due to prototype [259] */
+	take_int(0 - 2147483648);
+	/* expect+1: warning: integer overflow detected, op - [141] */
+	take_uint(0 - 2147483648U);
+}
+
+void
+fold_shl(void)
+{
+	/* expect+1: warning: integer overflow detected, op << [141] */
+	take_int(1 << 24 << 24);
+
+	/* expect+1: warning: integer overflow detected, op << [141] */
+	take_uint(1U << 24 << 24);
+
+	/* FIXME: undefined behavior in 'fold' at 'uint64_t << 104'. */
+	/* expect+1: warning: shift amount 104 is greater than bit-size 32 of 'unsigned int' [122] */
+	take_uint(1U << 24 << 104);
+}
+
+void
+fold_shr(void)
+{
+	take_int(16777216 >> 24);
+
+	take_int(16777216 >> 25);
+
+	/* FIXME: undefined behavior in 'fold' at 'uint64_t >> 104'. */
+	/* expect+1: warning: shift amount 104 is greater than bit-size 32 of 'int' [122] */
+	take_int(16777216 >> 104);
+}
+
+void
+fold_lt(void)
+{
+	take_bool(1 < 3);
+	take_bool(3 < 1);
+}
+
+void
+fold_le(void)
+{
+	take_bool(1 <= 3);
+	take_bool(3 <= 1);
+}
+
+void
+fold_ge(void)
+{
+	take_bool(1 >= 3);
+	take_bool(3 >= 1);
+}
+
+void
+fold_gt(void)
+{
+	take_bool(1 > 3);
+	take_bool(3 > 1);
+}
+
+void
+fold_eq(void)
+{
+	take_bool(1 == 3);
+	take_bool(3 == 1);
+}
+
+void
+fold_ne(void)
+{
+	take_bool(1 != 3);
+	take_bool(3 != 1);
+}
+
+void
+fold_bitand(void)
+{
+	take_bool(1 & 3);
+	take_bool(3 & 1);
+}
+
+void
+fold_bitxor(void)
+{
+	take_bool(1 ^ 3);
+	take_bool(3 ^ 1);
+}
+
+void
+fold_bitor(void)
+{
+	take_bool(1 | 3);
+	take_bool(3 | 1);
+}
Index: src/tests/usr.bin/xlint/lint1/expr_fold.exp
diff -u /dev/null src/tests/usr.bin/xlint/lint1/expr_fold.exp:1.1
--- /dev/null	Thu Aug 19 20:32:33 2021
+++ src/tests/usr.bin/xlint/lint1/expr_fold.exp	Thu Aug 19 20:32:33 2021
@@ -0,0 +1,55 @@
+expr_fold.c(35): warning: argument #1 is converted from 'long' to 'int' due to prototype [259]
+expr_fold.c(35): warning: conversion of 'long' to 'int' is out of range, arg #1 [295]
+expr_fold.c(39): warning: argument #1 is converted from 'long' to 'int' due to prototype [259]
+expr_fold.c(39): warning: conversion of 'long' to 'int' is out of range, arg #1 [295]
+expr_fold.c(44): warning: argument #1 is converted from 'long' to 'unsigned int' due to prototype [259]
+expr_fold.c(46): warning: argument #1 is converted from 'long' to 'unsigned int' due to prototype [259]
+expr_fold.c(64): warning: argument #1 is converted from 'long' to 'int' due to prototype [259]
+expr_fold.c(68): warning: argument #1 is converted from 'long' to 'int' due to prototype [259]
+expr_fold.c(72): warning: integer overflow detected, op + [141]
+expr_fold.c(72): warning: integer overflow detected, op - [141]
+expr_fold.c(74): warning: integer overflow detected, op - [141]
+expr_fold.c(77): warning: argument #1 is converted from 'long' to 'int' due to prototype [259]
+expr_fold.c(77): warning: conversion of 'long' to 'int' is out of range, arg #1 [295]
+expr_fold.c(82): warning: argument #1 is converted from 'int' to 'unsigned int' due to prototype [259]
+expr_fold.c(82): warning: conversion of negative constant to unsigned type, arg #1 [296]
+expr_fold.c(85): warning: argument #1 is converted from 'long' to 'unsigned int' due to prototype [259]
+expr_fold.c(85): warning: conversion of negative constant to unsigned type, arg #1 [296]
+expr_fold.c(88): warning: argument #1 is converted from 'long' to 'unsigned int' due to prototype [259]
+expr_fold.c(88): warning: conversion of negative constant to unsigned type, arg #1 [296]
+expr_fold.c(98): warning: argument #1 is converted from 'long' to 'int' due to prototype [259]
+expr_fold.c(98): warning: conversion of 'long' to 'int' is out of range, arg #1 [295]
+expr_fold.c(101): warning: argument #1 is converted from 'long' to 'int' due to prototype [259]
+expr_fold.c(101): warning: conversion of 'long' to 'int' is out of range, arg #1 [295]
+expr_fold.c(105): warning: argument #1 is converted from 'int' to 'unsigned int' due to prototype [259]
+expr_fold.c(105): warning: conversion of negative constant to unsigned type, arg #1 [296]
+expr_fold.c(108): warning: argument #1 is converted from 'int' to 'unsigned int' due to prototype [259]
+expr_fold.c(108): warning: conversion of negative constant to unsigned type, arg #1 [296]
+expr_fold.c(111): warning: argument #1 is converted from 'long' to 'unsigned int' due to prototype [259]
+expr_fold.c(111): warning: conversion of negative constant to unsigned type, arg #1 [296]
+expr_fold.c(114): warning: argument #1 is converted from 'long' to 'unsigned int' due to prototype [259]
+expr_fold.c(114): warning: conversion of negative constant to unsigned type, arg #1 [296]
+expr_fold.c(122): warning: integer overflow detected, op * [141]
+expr_fold.c(124): warning: integer overflow detected, op * [141]
+expr_fold.c(129): warning: integer overflow detected, op * [141]
+expr_fold.c(138): error: division by 0 [139]
+expr_fold.c(138): warning: integer overflow detected, op / [141]
+expr_fold.c(142): warning: argument #1 is converted from 'long' to 'int' due to prototype [259]
+expr_fold.c(142): warning: conversion of 'long' to 'int' is out of range, arg #1 [295]
+expr_fold.c(149): error: modulus by 0 [140]
+expr_fold.c(151): error: modulus by 0 [140]
+expr_fold.c(153): error: modulus by 0 [140]
+expr_fold.c(155): error: modulus by 0 [140]
+expr_fold.c(158): warning: argument #1 is converted from 'long' to 'int' due to prototype [259]
+expr_fold.c(165): warning: integer overflow detected, op + [141]
+expr_fold.c(171): warning: integer overflow detected, op + [141]
+expr_fold.c(179): warning: integer overflow detected, op + [141]
+expr_fold.c(181): warning: integer overflow detected, op + [141]
+expr_fold.c(188): warning: integer overflow detected, op - [141]
+expr_fold.c(192): warning: integer overflow detected, op - [141]
+expr_fold.c(195): warning: argument #1 is converted from 'long' to 'int' due to prototype [259]
+expr_fold.c(197): warning: integer overflow detected, op - [141]
+expr_fold.c(204): warning: integer overflow detected, op << [141]
+expr_fold.c(207): warning: integer overflow detected, op << [141]
+expr_fold.c(211): warning: shift amount 104 is greater than bit-size 32 of 'unsigned int' [122]
+expr_fold.c(223): warning: shift amount 104 is greater than bit-size 32 of 'int' [122]

Reply via email to