<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>