/*      $NetBSD: msg_129.c,v 1.10 2024/10/29 20:44:22 rillig Exp $      */
# 3 "msg_129.c"

// Test for message: expression has null effect [129]

/* lint1-extra-flags: -h -X 351 */

typedef unsigned char uint8_t;
typedef unsigned int uint32_t;

_Bool side_effect(void);

/*
* Before tree.c 1.198 from 2021-01-30, the nested comma operators were
* wrongly reported as having no side effect.
*
* The bug was that has_side_effect did not properly examine the sub-nodes.
* The ',' operator itself has m_has_side_effect == false since it depends
* on its operands whether the ',' actually has side effects.  For nested ','
* operators, the function did not evaluate the operands deeply but only did
* a quick shallow test on the m_has_side_effect property.  Since that is
* false, lint thought that the whole expression would have no side effect.
*/
void
uint8_buffer_write_uint32(uint8_t *c, uint32_t l)
{
       (*(c++) = (uint8_t)(l & 0xff),
           *(c++) = (uint8_t)((l >> 8L) & 0xff),
           *(c++) = (uint8_t)((l >> 16L) & 0xff),
           *(c++) = (uint8_t)((l >> 24L) & 0xff));
}

void
operator_comma(void)
{
       side_effect(), 0;               /* the 0 is redundant */
       /* expect+1: warning: expression has null effect [129] */
       0, side_effect();

       if (side_effect(), 0)           /* the 0 controls the 'if' */
               return;
       /* expect+1: warning: expression has null effect [129] */
       if (0, side_effect())
               return;
}

void
legitimate_use_cases(int arg)
{
       int local = 3;

       /*
        * This expression is commonly used to mark the parameter as
        * deliberately unused.
        */
       (void)arg;

       /*
        * This expression is commonly used to mark the local variable as
        * deliberately unused.  This situation occurs when the local
        * variable is only used in some but not all compile-time selectable
        * variants of the code, such as in debugging mode, and writing down
        * the exact conditions would complicate the code unnecessarily.
        */
       (void)local;

       /* This is a shorthand notation for a do-nothing command. */
       (void)0;

       /*
        * At the point where lint checks for expressions having a null
        * effect, constants have been folded, therefore the following
        * expression is considered safe as well.  It does not appear in
        * practice though.
        */
       (void)(3 - 3);

       /*
        * This variant of the do-nothing command is commonly used in
        * preprocessor macros since it works nicely with if-else and if-then
        * statements.  It is longer than the above variant, and it is not
        * embeddable into an expression.
        */
       do {
       } while (0);

       /*
        * Only the expression '(void)0' is common, other expressions are
        * unusual enough to warrant a warning.
        */
       /* expect+1: warning: expression has null effect [129] */
       (void)13;

       /* Double casts are unusual enough to warrant a warning. */
       /* expect+1: warning: expression has null effect [129] */
       (void)(void)0;
}

int
return_statement_expression(int arg)
{
       ({
               int local = arg;
               local + 4;
       /* expect+1: warning: expression has null effect [129] */
       });

       if (arg == 1)
               return ({
                       int local = arg;
                       // Before cgram.y 1.513 from 2024-10-29, lint wrongly
                       // warned that this expression would have a null effect.
                       local;
               });

       if (arg == 2)
               return ({
                       int local = arg;
                       // Before cgram.y 1.513 from 2024-10-29, lint wrongly
                       // warned that this expression would have a null effect.
                       local + 4;
               });

       return 0;
}