xref: /netbsd-src/tests/usr.bin/xlint/lint1/msg_324.c (revision d2c16d5796af7d64c26094d6e83f5c79714a35d6)
1*d2c16d57Srillig /*	$NetBSD: msg_324.c,v 1.10 2024/01/28 08:17:27 rillig Exp $	*/
2a0a15c14Srillig # 3 "msg_324.c"
3a0a15c14Srillig 
440a9b8fdSrillig // Test for message: suggest cast from '%s' to '%s' on op '%s' to avoid overflow [324]
5a0a15c14Srillig 
63796e6d4Srillig /*
73796e6d4Srillig  * This warning applies to binary operators if the result of the operator
83796e6d4Srillig  * is converted to a type that is bigger than the operands' result type
93796e6d4Srillig  * after the usual arithmetic promotions.
103796e6d4Srillig  *
113796e6d4Srillig  * In such a case, the operator's result would be truncated to the operator's
123796e6d4Srillig  * result type (invoking undefined behavior for signed integers), and that
133796e6d4Srillig  * truncated value would then be converted.  At that point, a few bits may
143796e6d4Srillig  * have been lost.
153796e6d4Srillig  */
163796e6d4Srillig 
17e6298b92Srillig /* lint1-flags: -g -S -w -P -X 351 */
183796e6d4Srillig 
193796e6d4Srillig void
example(char c,int i,unsigned u)203796e6d4Srillig example(char c, int i, unsigned u)
213796e6d4Srillig {
221aa2d357Srillig 	long long ll;
231aa2d357Srillig 	unsigned long long ull;
243796e6d4Srillig 
25*d2c16d57Srillig 	/* expect+2: warning: suggest cast from 'int' to 'long long' on op '+' to avoid overflow [324] */
26*d2c16d57Srillig 	/* expect+1: warning: 'll' set but not used in function 'example' [191] */
27ec42194bSrillig 	ll = c + i;
2840a9b8fdSrillig 	/* expect+1: warning: suggest cast from 'int' to 'long long' on op '-' to avoid overflow [324] */
29ec42194bSrillig 	ll = i - c;
30*d2c16d57Srillig 	/* expect+2: warning: suggest cast from 'unsigned int' to 'unsigned long long' on op '*' to avoid overflow [324] */
31*d2c16d57Srillig 	/* expect+1: warning: 'ull' set but not used in function 'example' [191] */
32ec42194bSrillig 	ull = c * u;
3340a9b8fdSrillig 	/* expect+1: warning: suggest cast from 'unsigned int' to 'unsigned long long' on op '+' to avoid overflow [324] */
34ec42194bSrillig 	ull = u + c;
3540a9b8fdSrillig 	/* expect+1: warning: suggest cast from 'unsigned int' to 'unsigned long long' on op '-' to avoid overflow [324] */
36ec42194bSrillig 	ull = i - u;
3740a9b8fdSrillig 	/* expect+1: warning: suggest cast from 'unsigned int' to 'unsigned long long' on op '*' to avoid overflow [324] */
38ec42194bSrillig 	ull = u * i;
3940a9b8fdSrillig 	/* expect+1: warning: suggest cast from 'int' to 'long long' on op '<<' to avoid overflow [324] */
40ec42194bSrillig 	ll = i << c;
413796e6d4Srillig 
423796e6d4Srillig 	/*
433796e6d4Srillig 	 * The operators SHR, DIV and MOD cannot produce an overflow,
443796e6d4Srillig 	 * therefore no warning is necessary for them.
453796e6d4Srillig 	 */
461aa2d357Srillig 	ll = i >> c;
471aa2d357Srillig 	ull = u / c;
481aa2d357Srillig 	ull = u % c;
4915275571Srillig 
5015275571Srillig 	/*
5115275571Srillig 	 * Assigning the result of an increment or decrement operator to a
5215275571Srillig 	 * differently-sized type is no unusual that there is no need to warn
5315275571Srillig 	 * about it.  It's also more unlikely that there is an actual loss
5415275571Srillig 	 * since this only happens for a single value of the old type, unlike
551aa2d357Srillig 	 * "ull = u * u", which has many more possibilities for overflowing.
5615275571Srillig 	 */
571aa2d357Srillig 	ull = u++;
581aa2d357Srillig 	ull = ++u;
591aa2d357Srillig 	ull = u--;
601aa2d357Srillig 	ull = --u;
613796e6d4Srillig }
62