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]