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