Home | History | Annotate | Line # | Download | only in lint1
msg_132.c revision 1.21
      1 /*	$NetBSD: msg_132.c,v 1.21 2022/07/03 14:35:54 rillig Exp $	*/
      2 # 3 "msg_132.c"
      3 
      4 // Test for message: conversion from '%s' to '%s' may lose accuracy [132]
      5 
      6 /*
      7  * NetBSD's default lint flags only include a single -a, which only flags
      8  * narrowing conversions from long.  To get warnings for all narrowing
      9  * conversions, -a needs to be given more than once.
     10  *
     11  * https://gnats.netbsd.org/14531
     12  */
     13 
     14 /* lint1-extra-flags: -aa */
     15 
     16 typedef unsigned char u8_t;
     17 typedef unsigned short u16_t;
     18 typedef unsigned int u32_t;
     19 typedef unsigned long long u64_t;
     20 typedef signed char s8_t;
     21 typedef signed short s16_t;
     22 typedef signed int s32_t;
     23 typedef signed long long s64_t;
     24 
     25 u8_t u8;
     26 u16_t u16;
     27 u32_t u32;
     28 u64_t u64;
     29 
     30 s8_t s8;
     31 s16_t s16;
     32 s32_t s32;
     33 s64_t s64;
     34 
     35 void
     36 unsigned_to_unsigned(void)
     37 {
     38 	/* expect+1: warning: conversion from 'unsigned short' to 'unsigned char' may lose accuracy [132] */
     39 	u8 = u16;
     40 	/* expect+1: warning: conversion from 'unsigned int' to 'unsigned char' may lose accuracy [132] */
     41 	u8 = u32;
     42 	/* expect+1: warning: conversion from 'unsigned long long' to 'unsigned char' may lose accuracy [132] */
     43 	u8 = u64;
     44 
     45 	u16 = u8;
     46 	/* expect+1: warning: conversion from 'unsigned int' to 'unsigned short' may lose accuracy [132] */
     47 	u16 = u32;
     48 	/* expect+1: warning: conversion from 'unsigned long long' to 'unsigned short' may lose accuracy [132] */
     49 	u16 = u64;
     50 
     51 	u32 = u8;
     52 	u32 = u16;
     53 	/* expect+1: warning: conversion from 'unsigned long long' to 'unsigned int' may lose accuracy [132] */
     54 	u32 = u64;
     55 
     56 	u64 = u8;
     57 	u64 = u16;
     58 	u64 = u32;
     59 }
     60 
     61 void
     62 unsigned_to_signed(void)
     63 {
     64 	/* expect+1: warning: conversion from 'unsigned short' to 'signed char' may lose accuracy [132] */
     65 	s8 = u16;
     66 	/* expect+1: warning: conversion from 'unsigned int' to 'signed char' may lose accuracy [132] */
     67 	s8 = u32;
     68 	/* expect+1: warning: conversion from 'unsigned long long' to 'signed char' may lose accuracy [132] */
     69 	s8 = u64;
     70 
     71 	s16 = u8;
     72 	/* expect+1: warning: conversion from 'unsigned int' to 'short' may lose accuracy [132] */
     73 	s16 = u32;
     74 	/* expect+1: warning: conversion from 'unsigned long long' to 'short' may lose accuracy [132] */
     75 	s16 = u64;
     76 
     77 	s32 = u8;
     78 	s32 = u16;
     79 	/* expect+1: warning: conversion from 'unsigned long long' to 'int' may lose accuracy [132] */
     80 	s32 = u64;
     81 
     82 	s64 = u8;
     83 	s64 = u16;
     84 	s64 = u32;
     85 }
     86 
     87 void
     88 signed_to_unsigned(void)
     89 {
     90 	/* expect+1: warning: conversion from 'short' to 'unsigned char' may lose accuracy [132] */
     91 	u8 = s16;
     92 	/* expect+1: warning: conversion from 'int' to 'unsigned char' may lose accuracy [132] */
     93 	u8 = s32;
     94 	/* expect+1: warning: conversion from 'long long' to 'unsigned char' may lose accuracy [132] */
     95 	u8 = s64;
     96 
     97 	u16 = s8;
     98 	/* expect+1: warning: conversion from 'int' to 'unsigned short' may lose accuracy [132] */
     99 	u16 = s32;
    100 	/* expect+1: warning: conversion from 'long long' to 'unsigned short' may lose accuracy [132] */
    101 	u16 = s64;
    102 
    103 	u32 = s8;
    104 	u32 = s16;
    105 	/* expect+1: warning: conversion from 'long long' to 'unsigned int' may lose accuracy [132] */
    106 	u32 = s64;
    107 
    108 	u64 = s8;
    109 	u64 = s16;
    110 	u64 = s32;
    111 }
    112 
    113 void
    114 signed_to_signed(void)
    115 {
    116 	/* expect+1: warning: conversion from 'short' to 'signed char' may lose accuracy [132] */
    117 	s8 = s16;
    118 	/* expect+1: warning: conversion from 'int' to 'signed char' may lose accuracy [132] */
    119 	s8 = s32;
    120 	/* expect+1: warning: conversion from 'long long' to 'signed char' may lose accuracy [132] */
    121 	s8 = s64;
    122 
    123 	s16 = s8;
    124 	/* expect+1: warning: conversion from 'int' to 'short' may lose accuracy [132] */
    125 	s16 = s32;
    126 	/* expect+1: warning: conversion from 'long long' to 'short' may lose accuracy [132] */
    127 	s16 = s64;
    128 
    129 	s32 = s8;
    130 	s32 = s16;
    131 	/* expect+1: warning: conversion from 'long long' to 'int' may lose accuracy [132] */
    132 	s32 = s64;
    133 
    134 	s64 = s8;
    135 	s64 = s16;
    136 	s64 = s32;
    137 }
    138 
    139 /*
    140  * Before tree.c 1.268 from 2021-04-06, lint wrongly warned that conversion
    141  * to _Bool might lose accuracy.  C99 6.3.1.2 defines a special conversion
    142  * rule from scalar to _Bool though by comparing the value to 0.
    143  */
    144 _Bool
    145 to_bool(long a, long b)
    146 {
    147 	/* seen in fp_lib.h, function wideRightShiftWithSticky */
    148 	return a | b;
    149 }
    150 
    151 /* ARGSUSED */
    152 const char *
    153 cover_build_plus_minus(const char *arr, double idx)
    154 {
    155 	/* expect+3: error: operands of '+' have incompatible types 'pointer' and 'double' [107] */
    156 	/* expect+2: warning: function 'cover_build_plus_minus' expects to return value [214] */
    157 	if (idx > 0.0)
    158 		return arr + idx;
    159 	return arr + (unsigned int)idx;
    160 }
    161 
    162 int
    163 non_constant_expression(void)
    164 {
    165 	/*
    166 	 * Even though this variable definition looks like a constant, it
    167 	 * does not fall within C's definition of an integer constant
    168 	 * expression.  Due to that, lint does not perform constant folding
    169 	 * on the expression built from this variable and thus doesn't know
    170 	 * that the conversion will always succeed.
    171 	 */
    172 	const int not_a_constant = 8;
    173 	/* expect+1: warning: conversion from 'unsigned long long' to 'int' may lose accuracy [132] */
    174 	return not_a_constant * 8ULL;
    175 }
    176 
    177 /*
    178  * PR 36668 notices that lint wrongly complains about the possible loss.
    179  *
    180  * The expression 'u8_t << 8' is guaranteed to fit into an 'u16_t', and its
    181  * lower 8 bits are guaranteed to be clear.  'u16_t | u8_t' is guaranteed to
    182  * fit into 'u16_t'.
    183  *
    184  * Since tree.c 1.444 from 2022-05-26, lint tracks simple bitwise and
    185  * arithmetic constraints across a single expression.
    186  */
    187 static inline u16_t
    188 be16dec(const void *buf)
    189 {
    190 	const u8_t *p = buf;
    191 
    192 	/*
    193 	 * Before tree.c 1.444 from 2022-05-26, lint complained that the
    194 	 * conversion from 'int' to 'unsigned short' may lose accuracy.
    195 	 */
    196 	return ((u16_t)p[0]) << 8 | p[1];
    197 }
    198 
    199 /*
    200  * Since tree.c 1.434 from 2022-04-19, lint infers the possible values of
    201  * expressions of the form 'integer & constant', see can_represent.
    202  */
    203 static inline void
    204 be32enc(void *buf, u32_t u)
    205 {
    206 	u8_t *p = buf;
    207 
    208 	p[0] = u >> 24 & 0xff;
    209 	p[1] = u >> 16 & 0xff;
    210 	p[2] = u >> 8 & 0xff;
    211 	p[3] = u & 0xff;
    212 }
    213 
    214 u32_t
    215 test_ic_shr(u64_t x)
    216 {
    217 	if (x > 3)
    218 		return x >> 32;
    219 	if (x > 2)
    220 		/* expect+1: warning: conversion from 'unsigned long long' to 'unsigned int' may lose accuracy [132] */
    221 		return x >> 31;
    222 	/* expect+1: warning: conversion from 'unsigned long long' to 'unsigned int' may lose accuracy [132] */
    223 	return x;
    224 }
    225 
    226 
    227 struct bit_fields {
    228 	unsigned bits_32: 32;
    229 	unsigned bits_5: 5;
    230 	unsigned bits_3: 3;
    231 };
    232 
    233 unsigned char
    234 test_bit_fields(struct bit_fields s, unsigned long long m)
    235 {
    236 	/* expect+1: warning: conversion from 'unsigned long long:32' to 'unsigned int:3' may lose accuracy [132] */
    237 	s.bits_3 = s.bits_32 & m;
    238 
    239 	s.bits_5 = s.bits_3 & m;
    240 	s.bits_32 = s.bits_5 & m;
    241 
    242 	/* expect+1: warning: conversion from 'unsigned long long:32' to 'unsigned char' may lose accuracy [132] */
    243 	return s.bits_32 & m;
    244 }
    245 
    246 u64_t
    247 u64_shl(u64_t lhs, u64_t rhs)
    248 {
    249 	return lhs << rhs;
    250 }
    251 
    252 u64_t
    253 u64_shr(u64_t lhs, u64_t rhs)
    254 {
    255 	return lhs >> rhs;
    256 }
    257 
    258 s64_t
    259 s64_shl(s64_t lhs, s64_t rhs)
    260 {
    261 	return lhs << rhs;
    262 }
    263 
    264 s64_t
    265 s64_shr(s64_t lhs, s64_t rhs)
    266 {
    267 	return lhs >> rhs;
    268 }
    269