<html>
    <head>
      <base href="https://bugs.llvm.org/">
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - Warn-unused-results warnings with expression statements dependent on whether the expr-stmt was typed or generated by the preprocessor"
   href="https://bugs.llvm.org/show_bug.cgi?id=39367">39367</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Warn-unused-results warnings with expression statements dependent on whether the expr-stmt was typed or generated by the preprocessor
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>clang
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>unspecified
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>Linux
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>enhancement
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>Frontend
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedclangbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>pskocik@gmail.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Hi, my problem appears related to <a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - -Wunused-value and statement expressions"
   href="show_bug.cgi?id=8218">https://bugs.llvm.org/show_bug.cgi?id=8218</a>
and
<a class="bz_bug_link 
          bz_status_RESOLVED  bz_closed"
   title="RESOLVED FIXED - [linux kernel] -Wunused-value should not warn about unused statement expression result expanded from a macro"
   href="show_bug.cgi?id=13747">https://bugs.llvm.org/show_bug.cgi?id=13747</a>

I'm getting some very weird behavior out clang regarding the unused-value
warnings.

This compiles without a warning with `clang -c file.c`:

        void fail(void); long f(void); void g(void);
        #define CHK(X) (__extension__ ({ long CHK=X; if(0>CHK) fail(); else{;}
(void)CHK; CHK; }))
        int main()
        {
                int n = 0;
                f();
                CHK(f());
                switch(n){case 0: CHK(f()); }
                #define SWITCH(...) switch(n){ __VA_ARGS__ }
                SWITCH(case 0: f(); )

                #if OOPS
                SWITCH(case 0: CHK(f()); )
                #endif
        }

but enabling the last swith with the pasted block generates an unused-value
warning.
`clang -DOOPS file.c -c`. Perhaps even more shockingly even without the `OOPS`
macro being truthy,
the program generates two warnings (or 3 `#if !!OOPS`) if compiled with `clang
file.c -E |clang -xc - -c`,
which ought to give the same result as `clang file.c -c`.

Complete set of examples (creates file.c in the $PWD):

        #!/bin/sh -eu
        cat > file.c <<EOF
        void fail(void); long f(void); void g(void);
        #define CHK(X) (__extension__ ({ long CHK=X; if(0>CHK) fail(); else{;}
(void)CHK; CHK; }))
        int main()
        {
                int n = 0;
                f();
                CHK(f());
                switch(n){case 0: CHK(f()); }
                #define SWITCH(...) switch(n){ __VA_ARGS__ }
                SWITCH(case 0: f(); )

                #if OOPS
                SWITCH(case 0: CHK(f()); )
                #endif
        }
        EOF
        clang -v 2>&1 |head -n1
        echo NO WUR
        clang -Wall file.c -c
        echo WUR ON OOPS=1
        clang -Wall -DOOPS=1 file.c -c
        echo WUR ON SEPARATE PREPROCESSING "(NO OOPS)"
        clang -E -Wall file.c  |clang -xc - -o /dev/null -c

My output:

        clang version 6.0.0-1ubuntu2 (tags/RELEASE_600/final)
        NO WUR
        WUR ON OOPS=1
        file.c:13:17: warning: expression result unused [-Wunused-value]
                        SWITCH(case 0: CHK(f()); )
                                                   ^~~~~~~~
        file.c:2:83: note: expanded from macro 'CHK'
        #define CHK(X) (__extension__ ({ long CHK=X; if(0>CHK) fail(); else{;}
(void)CHK; CHK; }))
                                                                               
                                                                               
          ^~~
        file.c:9:33: note: expanded from macro 'SWITCH'
                        #define SWITCH(...) switch(n){ __VA_ARGS__ }
                                                                               
   ^~~~~~~~~~~
        1 warning generated.
        WUR ON SEPARATE PREPROCESSING (NO OOPS)
        file.c:8:89: warning: expression result unused [-Wunused-value]
         switch(n){case 0: (__extension__ ({ long CHK=f(); if(0>CHK) fail();
else{;} (void)CHK; CHK; })); }
                                                                               
                                                                               
                        ^~~
        file.c:7:71: warning: expression result unused [-Wunused-value]
         (__extension__ ({ long CHK=f(); if(0>CHK) fail(); else{;} (void)CHK;
CHK; }));
                                                                               
                                                                  ^~~
        2 warnings generated.


Suggestion:

Either disable unused-value warnings for expression statements like gcc does it
or (better)
allow __attribute((warn_unused_result)) on variables and if that variable is
used for the "return" value of 
an expression statement, treat that expression statement like a function call
to a function with the
`warn-unused-result` attribute.

In my opinion, expr statements are kind of like function calls anyway, so it'd
make sense to be able to somehow stick a warn-unused-result attribute to them.

Another idea, if clang wants to warn on unused expr-stmts by default, might be
to suppres the warning if the expr-stmt evaluates to a variable mark with the
unused attribute.

E.g., perhaps:

        #define CHK(X) (__extension__ ({ long __attribute__((unused))
/*<-ADDED*/ CHK=X; if(0>CHK) fail(); else{;} (void)CHK; CHK; /*UNUSED ATTR*/}))

should never generate an unused result warning.

Thanks for consideration.

Best regards,
Petr Skocik</pre>
        </div>
      </p>


      <hr>
      <span>You are receiving this mail because:</span>

      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>