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