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