Home | History | Annotate | Line # | Download | only in lint1
msg_129.c revision 1.5
      1  1.5  rillig /*	$NetBSD: msg_129.c,v 1.5 2021/08/21 08:18:48 rillig Exp $	*/
      2  1.1  rillig # 3 "msg_129.c"
      3  1.1  rillig 
      4  1.1  rillig // Test for message: expression has null effect [129]
      5  1.1  rillig 
      6  1.2  rillig /* lint1-extra-flags: -h */
      7  1.2  rillig 
      8  1.2  rillig typedef unsigned char uint8_t;
      9  1.2  rillig typedef unsigned int uint32_t;
     10  1.2  rillig 
     11  1.3  rillig _Bool side_effect(void);
     12  1.3  rillig 
     13  1.2  rillig /*
     14  1.3  rillig  * Before tree.c 1.198 from 2021-01-30, the nested comma operators were
     15  1.3  rillig  * wrongly reported as having no side effect.
     16  1.2  rillig  *
     17  1.3  rillig  * The bug was that has_side_effect did not properly examine the sub-nodes.
     18  1.4  rillig  * The ',' operator itself has m_has_side_effect == false since it depends
     19  1.4  rillig  * on its operands whether the ',' actually has side effects.  For nested ','
     20  1.3  rillig  * operators, the function did not evaluate the operands deeply but only did
     21  1.3  rillig  * a quick shallow test on the m_has_side_effect property.  Since that is
     22  1.3  rillig  * false, lint thought that the whole expression would have no side effect.
     23  1.2  rillig  */
     24  1.2  rillig void
     25  1.2  rillig uint8_buffer_write_uint32(uint8_t *c, uint32_t l)
     26  1.2  rillig {
     27  1.2  rillig 	(*(c++) = (uint8_t)(l & 0xff),
     28  1.2  rillig 	    *(c++) = (uint8_t)((l >> 8L) & 0xff),
     29  1.2  rillig 	    *(c++) = (uint8_t)((l >> 16L) & 0xff),
     30  1.3  rillig 	    *(c++) = (uint8_t)((l >> 24L) & 0xff));
     31  1.3  rillig }
     32  1.3  rillig 
     33  1.3  rillig void
     34  1.3  rillig operator_comma(void)
     35  1.3  rillig {
     36  1.3  rillig 	side_effect(), 0;		/* the 0 is redundant */
     37  1.3  rillig 	0, side_effect();		/* expect: 129 */
     38  1.3  rillig 
     39  1.3  rillig 	if (side_effect(), 0)		/* the 0 controls the 'if' */
     40  1.3  rillig 		return;
     41  1.3  rillig 	if (0, side_effect())		/* expect: 129 */
     42  1.3  rillig 		return;
     43  1.2  rillig }
     44  1.4  rillig 
     45  1.4  rillig void
     46  1.4  rillig legitimate_use_cases(int arg)
     47  1.4  rillig {
     48  1.4  rillig 	int local = 3;
     49  1.4  rillig 
     50  1.4  rillig 	/*
     51  1.4  rillig 	 * This expression is commonly used to mark the argument as
     52  1.4  rillig 	 * deliberately unused.
     53  1.4  rillig 	 */
     54  1.4  rillig 	(void)arg;
     55  1.4  rillig 
     56  1.4  rillig 	/*
     57  1.4  rillig 	 * This expression is commonly used to mark the local variable as
     58  1.4  rillig 	 * deliberately unused.  This situation occurs when the local
     59  1.4  rillig 	 * variable is only used in some but not all compile-time selectable
     60  1.4  rillig 	 * variants of the code, such as in debugging mode, and writing down
     61  1.4  rillig 	 * the exact conditions would complicate the code unnecessarily.
     62  1.4  rillig 	 */
     63  1.4  rillig 	(void)local;
     64  1.4  rillig 
     65  1.4  rillig 	/* This is a short-hand notation for a do-nothing command. */
     66  1.4  rillig 	(void)0;
     67  1.4  rillig 
     68  1.4  rillig 	/*
     69  1.5  rillig 	 * At the point where lint checks for expressions having a null
     70  1.5  rillig 	 * effect, constants have been folded, therefore the following
     71  1.5  rillig 	 * expression is considered safe as well.  It does not appear in
     72  1.5  rillig 	 * practice though.
     73  1.5  rillig 	 */
     74  1.5  rillig 	(void)(3 - 3);
     75  1.5  rillig 
     76  1.5  rillig 	/*
     77  1.4  rillig 	 * This variant of the do-nothing command is commonly used in
     78  1.4  rillig 	 * preprocessor macros since it works nicely with if-else and if-then
     79  1.4  rillig 	 * statements.  It is longer than the above variant though.
     80  1.4  rillig 	 */
     81  1.4  rillig 	do {
     82  1.4  rillig 	} while (0);
     83  1.4  rillig 
     84  1.4  rillig 	/*
     85  1.4  rillig 	 * Only the expression '(void)0' is common, other expressions are
     86  1.5  rillig 	 * unusual enough to warrant a warning.
     87  1.4  rillig 	 */
     88  1.4  rillig 	/* expect+1: warning: expression has null effect [129] */
     89  1.4  rillig 	(void)13;
     90  1.5  rillig 
     91  1.5  rillig 	/* Double casts are unusual enough to warrant a warning. */
     92  1.5  rillig 	/* expect+1: warning: expression has null effect [129] */
     93  1.5  rillig 	(void)(void)0;
     94  1.4  rillig }
     95