[llvm-bugs] [Bug 39367] New: Warn-unused-results warnings with expression statements dependent on whether the expr-stmt was typed or generated by the preprocessor

via llvm-bugs llvm-bugs at lists.llvm.org
Sat Oct 20 03:50:58 PDT 2018


https://bugs.llvm.org/show_bug.cgi?id=39367

            Bug ID: 39367
           Summary: Warn-unused-results warnings with expression
                    statements dependent on whether the expr-stmt was
                    typed or generated by the preprocessor
           Product: clang
           Version: unspecified
          Hardware: PC
                OS: Linux
            Status: NEW
          Severity: enhancement
          Priority: P
         Component: Frontend
          Assignee: unassignedclangbugs at nondot.org
          Reporter: pskocik at gmail.com
                CC: llvm-bugs at lists.llvm.org

Hi, my problem appears related to https://bugs.llvm.org/show_bug.cgi?id=8218
and
https://bugs.llvm.org/show_bug.cgi?id=13747

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

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20181020/f79eee00/attachment.html>


More information about the llvm-bugs mailing list