The Conditional Operator and Unused Results

I submitted [bug 8282], which is that statements like (x?y++:0) will
warn about an unused result for the 0. This idiom occurs in macros for
control flow, ie, in CPU_SET.

Currently, (x ? y : z) warns if either y or z would warn. Should this be
changed to warn only if both y and z would warn?

[bug 8282]: http://llvm.org/bugs/show_bug.cgi?id=8282

What is the real-world code you're seeing this on, and what diagnostic are you getting?

-Chris

Chris Lattner <clattner@apple.com> writes:

What is the real-world code you're seeing this on, and what diagnostic are you getting?

There are two cases in the code base I was compiling. The first is
setting up a threading domain, of which the relevent bits are simply:

    #define _GNU_SOURCE
    #include <sched.h>
    extern cpu_set_t cpuMask;
    
    void setCpuAffinity(const int cpu)
    {
        CPU_ZERO( &cpuMask );
        CPU_SET( cpu, &cpuMask );
    }

This gives me:

    $ ./Debug+Asserts/bin/clang -fsyntax-only ~/tmp/cpuset.c
    /home/bogner/tmp/cpuset.c:8:5: warning: expression result unused [-Wunused-value]
        CPU_SET( cpu, &cpuMask );
        ^~~~~~~~~~~~~~~~~~~~~~~~
    In file included from /home/bogner/tmp/cpuset.c:2:
    /usr/include/sched.h:72:33: note: instantiated from:
    # define CPU_SET(cpu, cpusetp) __CPU_SET_S (cpu, sizeof (cpu_set_t), cpusetp)
                                     ^
    In file included from /home/bogner/tmp/cpuset.c:2:
    In file included from /usr/include/sched.h:35:
    /usr/include/bits/sched.h:145:9: note: instantiated from:
          : 0; }))
            ^
    1 warning generated.

This is the more serious case, because It's not easy to suppress
warnings from standard headers. The other case involved an iterator
foreach macro, which has something like:

    for (...; ...; doNextIteration ? ++i : i)

This one's not so bad, as I can change it to:

    for (...; ...; (void)(doNextIteration ? ++i : i))

Justin Bogner <mail@justinbogner.com> writes:

Currently, (x ? y : z) warns if either y or z would warn. Should this be
changed to warn only if both y and z would warn?

The attached patch implements this behaviour.

conditionally-unused.patch (1.54 KB)

I opened http://llvm.org/bugs/show_bug.cgi?id=8218 about this a few days
ago. GCC heuristic seems that the return value of an expression
statement not being used is just fine.

And like I say in the bug report it makes sense because expression
statements are usually used through a macro, that looks like a funcall,
and well, if clang doesn't warn if you don't catch the return value of a
function call, then it shouldn't warn if you don't catch the return
value of an expression statement.

And I even provided a patch now for that. It fixes the CPU_SET case.