Home | History | Annotate | Line # | Download | only in lint1
msg_132.c revision 1.11
      1 /*	$NetBSD: msg_132.c,v 1.11 2022/05/26 09:26:00 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 unsigned char u8;
     17 unsigned short u16;
     18 unsigned int u32;
     19 unsigned long long u64;
     20 
     21 signed char s8;
     22 signed short s16;
     23 signed int s32;
     24 signed long long s64;
     25 
     26 void
     27 unsigned_to_unsigned(void)
     28 {
     29 	u8 = u16;		/* expect: 132 */
     30 	u8 = u32;		/* expect: 132 */
     31 	u8 = u64;		/* expect: 132 */
     32 
     33 	u16 = u8;
     34 	u16 = u32;		/* expect: 132 */
     35 	u16 = u64;		/* expect: 132 */
     36 
     37 	u32 = u8;
     38 	u32 = u16;
     39 	u32 = u64;		/* expect: 132 */
     40 
     41 	u64 = u8;
     42 	u64 = u16;
     43 	u64 = u32;
     44 }
     45 
     46 void
     47 unsigned_to_signed(void)
     48 {
     49 	s8 = u16;		/* expect: 132 */
     50 	s8 = u32;		/* expect: 132 */
     51 	s8 = u64;		/* expect: 132 */
     52 
     53 	s16 = u8;
     54 	s16 = u32;		/* expect: 132 */
     55 	s16 = u64;		/* expect: 132 */
     56 
     57 	s32 = u8;
     58 	s32 = u16;
     59 	s32 = u64;		/* expect: 132 */
     60 
     61 	s64 = u8;
     62 	s64 = u16;
     63 	s64 = u32;
     64 }
     65 
     66 void
     67 signed_to_unsigned(void)
     68 {
     69 	u8 = s16;		/* expect: 132 */
     70 	u8 = s32;		/* expect: 132 */
     71 	u8 = s64;		/* expect: 132 */
     72 
     73 	u16 = s8;
     74 	u16 = s32;		/* expect: 132 */
     75 	u16 = s64;		/* expect: 132 */
     76 
     77 	u32 = s8;
     78 	u32 = s16;
     79 	u32 = s64;		/* expect: 132 */
     80 
     81 	u64 = s8;
     82 	u64 = s16;
     83 	u64 = s32;
     84 }
     85 
     86 void
     87 signed_to_signed(void)
     88 {
     89 	s8 = s16;		/* expect: 132 */
     90 	s8 = s32;		/* expect: 132 */
     91 	s8 = s64;		/* expect: 132 */
     92 
     93 	s16 = s8;
     94 	s16 = s32;		/* expect: 132 */
     95 	s16 = s64;		/* expect: 132 */
     96 
     97 	s32 = s8;
     98 	s32 = s16;
     99 	s32 = s64;		/* expect: 132 */
    100 
    101 	s64 = s8;
    102 	s64 = s16;
    103 	s64 = s32;
    104 }
    105 
    106 /*
    107  * Before tree.c 1.268 from 2021-04-06, lint wrongly warned that conversion
    108  * to _Bool might lose accuracy.  C99 6.3.1.2 defines a special conversion
    109  * rule from scalar to _Bool though by comparing the value to 0.
    110  */
    111 _Bool
    112 to_bool(long a, long b)
    113 {
    114 	/* seen in fp_lib.h, function wideRightShiftWithSticky */
    115 	return a | b;
    116 }
    117 
    118 /* ARGSUSED */
    119 const char *
    120 cover_build_plus_minus(const char *arr, double idx)
    121 {
    122 	/* expect+3: error: operands of '+' have incompatible types (pointer != double) [107] */
    123 	/* expect+2: warning: function 'cover_build_plus_minus' expects to return value [214] */
    124 	if (idx > 0.0)
    125 		return arr + idx;
    126 	return arr + (unsigned int)idx;
    127 }
    128 
    129 int
    130 non_constant_expression(void)
    131 {
    132 	/*
    133 	 * Even though this variable definition looks like a constant, it
    134 	 * does not fall within C's definition of an integer constant
    135 	 * expression.  Due to that, lint does not perform constant folding
    136 	 * on the expression built from this variable and thus doesn't know
    137 	 * that the conversion will always succeed.
    138 	 */
    139 	const int not_a_constant = 8;
    140 	/* expect+1: warning: conversion from 'unsigned long long' to 'int' may lose accuracy [132] */
    141 	return not_a_constant * 8ULL;
    142 }
    143 
    144 typedef unsigned char u8_t;
    145 typedef unsigned short u16_t;
    146 typedef unsigned int u32_t;
    147 typedef unsigned long long u64_t;
    148 
    149 /*
    150  * PR 36668 notices that lint wrongly complains about the possible loss.
    151  *
    152  * The expression 'u8_t << 8' is guaranteed to fit into an 'u16_t', and its
    153  * lower 8 bits are guaranteed to be clear.  'u16_t | u8_t' is guaranteed to
    154  * fit into 'u16_t'.
    155  *
    156  * Since tree.c 1.444 from 2022-05-26, lint tracks simple bitwise and
    157  * arithmetic constraints across a single expression.
    158  */
    159 static inline u16_t
    160 be16dec(const void *buf)
    161 {
    162 	const u8_t *p = buf;
    163 
    164 	/*
    165 	 * Before tree.c 1.444 from 2022-05-26, lint complained that the
    166 	 * conversion from 'int' to 'unsigned short' may lose accuracy.
    167 	 */
    168 	return ((u16_t)p[0]) << 8 | p[1];
    169 }
    170 
    171 /*
    172  * Since tree.c 1.434 from 2022-04-19, lint infers the possible values of
    173  * expressions of the form 'integer & constant', see can_represent.
    174  */
    175 static inline void
    176 be32enc(void *buf, u32_t u)
    177 {
    178 	u8_t *p = buf;
    179 
    180 	p[0] = u >> 24 & 0xff;
    181 	p[1] = u >> 16 & 0xff;
    182 	p[2] = u >> 8 & 0xff;
    183 	p[3] = u & 0xff;
    184 }
    185