Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src tests/lint: test folding of constant expressions



details:   https://anonhg.NetBSD.org/src/rev/9db12ecc9c48
branches:  trunk
changeset: 1023024:9db12ecc9c48
user:      rillig <rillig%NetBSD.org@localhost>
date:      Thu Aug 19 20:32:33 2021 +0000

description:
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.

diffstat:

 distrib/sets/lists/tests/mi             |    4 +-
 tests/usr.bin/xlint/check-expect.lua    |    4 +-
 tests/usr.bin/xlint/lint1/Makefile      |    4 +-
 tests/usr.bin/xlint/lint1/expr_fold.c   |  287 ++++++++++++++++++++++++++++++++
 tests/usr.bin/xlint/lint1/expr_fold.exp |   55 ++++++
 5 files changed, 350 insertions(+), 4 deletions(-)

diffs (truncated from 405 to 300 lines):

diff -r c9df6004f843 -r 9db12ecc9c48 distrib/sets/lists/tests/mi
--- a/distrib/sets/lists/tests/mi       Thu Aug 19 20:08:25 2021 +0000
+++ b/distrib/sets/lists/tests/mi       Thu Aug 19 20:32:33 2021 +0000
@@ -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
diff -r c9df6004f843 -r 9db12ecc9c48 tests/usr.bin/xlint/check-expect.lua
--- a/tests/usr.bin/xlint/check-expect.lua      Thu Aug 19 20:08:25 2021 +0000
+++ b/tests/usr.bin/xlint/check-expect.lua      Thu Aug 19 20:32:33 2021 +0000
@@ -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 @@
     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
 
diff -r c9df6004f843 -r 9db12ecc9c48 tests/usr.bin/xlint/lint1/Makefile
--- a/tests/usr.bin/xlint/lint1/Makefile        Thu Aug 19 20:08:25 2021 +0000
+++ b/tests/usr.bin/xlint/lint1/Makefile        Thu Aug 19 20:32:33 2021 +0000
@@ -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.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
diff -r c9df6004f843 -r 9db12ecc9c48 tests/usr.bin/xlint/lint1/expr_fold.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/usr.bin/xlint/lint1/expr_fold.c     Thu Aug 19 20:32:33 2021 +0000
@@ -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)



Home | Main Index | Thread Index | Old Index