2010-09-20 07:03:35 +08:00
|
|
|
// RUN: %clang_cc1 -fsyntax-only -verify %s -Wno-unreachable-code
|
2007-06-27 13:58:33 +08:00
|
|
|
|
|
|
|
int foo(int X, int Y);
|
|
|
|
|
2010-01-08 10:20:44 +08:00
|
|
|
double sqrt(double X); // implicitly const because of no -fmath-errno!
|
2009-02-17 08:35:09 +08:00
|
|
|
|
2007-06-27 13:58:33 +08:00
|
|
|
void bar(volatile int *VP, int *P, int A,
|
|
|
|
_Complex double C, volatile _Complex double VC) {
|
|
|
|
|
2014-03-11 11:11:08 +08:00
|
|
|
VP < P; // expected-warning {{relational comparison result unused}}
|
2007-08-27 01:32:59 +08:00
|
|
|
(void)A;
|
2007-06-27 13:58:33 +08:00
|
|
|
(void)foo(1,2); // no warning.
|
|
|
|
|
2014-03-11 11:11:08 +08:00
|
|
|
A < foo(1, 2); // expected-warning {{relational comparison result unused}}
|
2007-06-27 13:58:33 +08:00
|
|
|
|
|
|
|
foo(1,2)+foo(4,3); // expected-warning {{expression result unused}}
|
|
|
|
|
|
|
|
|
|
|
|
*P; // expected-warning {{expression result unused}}
|
|
|
|
*VP; // no warning.
|
|
|
|
P[4]; // expected-warning {{expression result unused}}
|
|
|
|
VP[4]; // no warning.
|
|
|
|
|
2009-02-17 08:32:04 +08:00
|
|
|
__real__ C; // expected-warning {{expression result unused}}
|
|
|
|
__real__ VC;
|
2009-02-17 08:35:09 +08:00
|
|
|
|
2010-01-08 10:20:44 +08:00
|
|
|
// We know this can't change errno because of no -fmath-errno.
|
2009-10-13 12:53:48 +08:00
|
|
|
sqrt(A); // expected-warning {{ignoring return value of function declared with const attribute}}
|
2007-06-27 13:58:33 +08:00
|
|
|
}
|
|
|
|
|
2007-08-27 01:32:59 +08:00
|
|
|
extern void t1();
|
|
|
|
extern void t2();
|
|
|
|
void t3(int c) {
|
|
|
|
c ? t1() : t2();
|
|
|
|
}
|
|
|
|
|
2007-09-01 05:49:55 +08:00
|
|
|
// This shouldn't warn: the expr at the end of the stmtexpr really is used.
|
|
|
|
int stmt_expr(int x, int y) {
|
|
|
|
return ({int _a = x, _b = y; _a > _b ? _a : _b; });
|
|
|
|
}
|
|
|
|
|
2008-05-20 05:24:43 +08:00
|
|
|
void nowarn(unsigned char* a, unsigned char* b)
|
|
|
|
{
|
|
|
|
unsigned char c = 1;
|
|
|
|
*a |= c, *b += c;
|
2009-07-29 02:25:28 +08:00
|
|
|
|
|
|
|
|
|
|
|
// PR4633
|
|
|
|
int y, x;
|
|
|
|
((void)0), y = x;
|
2008-05-20 05:24:43 +08:00
|
|
|
}
|
2009-07-29 02:25:28 +08:00
|
|
|
|
2009-07-31 06:39:03 +08:00
|
|
|
void t4(int a) {
|
|
|
|
int b = 0;
|
|
|
|
|
|
|
|
if (a)
|
2014-03-11 11:11:08 +08:00
|
|
|
b < 1; // expected-warning{{relational comparison result unused}}
|
2009-07-31 06:39:03 +08:00
|
|
|
else
|
2014-03-11 11:11:08 +08:00
|
|
|
b < 2; // expected-warning{{relational comparison result unused}}
|
2009-07-31 06:39:03 +08:00
|
|
|
|
|
|
|
while (1)
|
2014-03-11 11:11:08 +08:00
|
|
|
b < 3; // expected-warning{{relational comparison result unused}}
|
2009-07-31 06:39:03 +08:00
|
|
|
|
|
|
|
do
|
2014-03-11 11:11:08 +08:00
|
|
|
b < 4; // expected-warning{{relational comparison result unused}}
|
2009-07-31 06:39:03 +08:00
|
|
|
while (1);
|
|
|
|
|
|
|
|
for (;;)
|
2014-03-11 11:11:08 +08:00
|
|
|
b < 5; // expected-warning{{relational comparison result unused}}
|
2009-08-01 09:39:59 +08:00
|
|
|
|
2014-03-11 11:11:08 +08:00
|
|
|
for (b < 1;;) {} // expected-warning{{relational comparison result unused}}
|
2011-08-17 17:34:37 +08:00
|
|
|
for (;b < 1;) {}
|
2014-03-11 11:11:08 +08:00
|
|
|
for (;;b < 1) {} // expected-warning{{relational comparison result unused}}
|
2009-07-31 06:39:03 +08:00
|
|
|
}
|
|
|
|
|
2009-10-13 12:53:48 +08:00
|
|
|
// rdar://7186119
|
|
|
|
int t5f(void) __attribute__((warn_unused_result));
|
|
|
|
void t5() {
|
2016-03-08 06:44:55 +08:00
|
|
|
t5f(); // expected-warning {{ignoring return value of function declared with 'warn_unused_result' attribute}}
|
2009-10-13 12:53:48 +08:00
|
|
|
}
|
2009-10-13 12:56:49 +08:00
|
|
|
|
|
|
|
|
|
|
|
int fn1() __attribute__ ((warn_unused_result));
|
|
|
|
int fn2() __attribute__ ((pure));
|
2012-08-14 02:04:58 +08:00
|
|
|
int fn3() __attribute__ ((__const));
|
2009-10-13 12:57:27 +08:00
|
|
|
// rdar://6587766
|
2009-10-13 12:56:49 +08:00
|
|
|
int t6() {
|
|
|
|
if (fn1() < 0 || fn2(2,1) < 0 || fn3(2) < 0) // no warnings
|
|
|
|
return -1;
|
2009-12-23 07:59:52 +08:00
|
|
|
|
2016-03-08 06:44:55 +08:00
|
|
|
fn1(); // expected-warning {{ignoring return value of function declared with 'warn_unused_result' attribute}}
|
2009-10-13 12:56:49 +08:00
|
|
|
fn2(92, 21); // expected-warning {{ignoring return value of function declared with pure attribute}}
|
|
|
|
fn3(42); // expected-warning {{ignoring return value of function declared with const attribute}}
|
2014-01-23 11:51:55 +08:00
|
|
|
__builtin_abs(0); // expected-warning {{ignoring return value of function declared with const attribute}}
|
2016-03-08 06:44:55 +08:00
|
|
|
(void)0, fn1(); // expected-warning {{ignoring return value of function declared with 'warn_unused_result' attribute}}
|
2009-10-13 12:56:49 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2011-01-25 11:51:08 +08:00
|
|
|
int t7 __attribute__ ((warn_unused_result)); // expected-warning {{'warn_unused_result' attribute only applies to functions}}
|
2009-10-13 12:56:49 +08:00
|
|
|
|
2009-12-21 07:11:08 +08:00
|
|
|
// PR4010
|
|
|
|
int (*fn4)(void) __attribute__ ((warn_unused_result));
|
|
|
|
void t8() {
|
2016-03-08 06:44:55 +08:00
|
|
|
fn4(); // expected-warning {{ignoring return value of function declared with 'warn_unused_result' attribute}}
|
2009-12-21 07:11:08 +08:00
|
|
|
}
|
2009-12-23 07:59:52 +08:00
|
|
|
|
|
|
|
void t9() __attribute__((warn_unused_result)); // expected-warning {{attribute 'warn_unused_result' cannot be applied to functions without return value}}
|
2010-04-07 06:24:14 +08:00
|
|
|
|
|
|
|
// rdar://7410924
|
|
|
|
void *some_function(void);
|
|
|
|
void t10() {
|
|
|
|
(void*) some_function(); //expected-warning {{expression result unused; should this cast be to 'void'?}}
|
|
|
|
}
|
2010-05-09 06:41:50 +08:00
|
|
|
|
|
|
|
void f(int i, ...) {
|
|
|
|
__builtin_va_list ap;
|
|
|
|
|
|
|
|
__builtin_va_start(ap, i);
|
|
|
|
__builtin_va_arg(ap, int);
|
|
|
|
__builtin_va_end(ap);
|
|
|
|
}
|
2010-10-15 16:44:44 +08:00
|
|
|
|
|
|
|
// PR8371
|
|
|
|
int fn5() __attribute__ ((__const));
|
2012-10-24 07:19:32 +08:00
|
|
|
|
2013-01-17 10:06:08 +08:00
|
|
|
// Don't warn for unused expressions in macro bodies; however, do warn for
|
|
|
|
// unused expressions in macro arguments. Macros below are reduced from code
|
|
|
|
// found in the wild.
|
|
|
|
#define NOP(a) (a)
|
2012-10-24 09:14:28 +08:00
|
|
|
#define M1(a, b) (long)foo((a), (b))
|
|
|
|
#define M2 (long)0;
|
2013-01-17 10:06:08 +08:00
|
|
|
#define M3(a) (t3(a), fn2())
|
|
|
|
#define M4(a, b) (foo((a), (b)) ? 0 : t3(a), 1)
|
|
|
|
#define M5(a, b) (foo((a), (b)), 1)
|
2013-02-27 03:34:08 +08:00
|
|
|
#define M6() fn1()
|
|
|
|
#define M7() fn2()
|
2012-10-24 07:19:32 +08:00
|
|
|
void t11(int i, int j) {
|
2012-10-24 09:14:28 +08:00
|
|
|
M1(i, j); // no warning
|
2013-01-17 10:06:08 +08:00
|
|
|
NOP((long)foo(i, j)); // expected-warning {{expression result unused}}
|
|
|
|
M2; // no warning
|
|
|
|
NOP((long)0); // expected-warning {{expression result unused}}
|
|
|
|
M3(i); // no warning
|
|
|
|
NOP((t3(i), fn2())); // expected-warning {{ignoring return value}}
|
|
|
|
M4(i, j); // no warning
|
|
|
|
NOP((foo(i, j) ? 0 : t3(i), 1)); // expected-warning {{expression result unused}}
|
|
|
|
M5(i, j); // no warning
|
|
|
|
NOP((foo(i, j), 1)); // expected-warning {{expression result unused}}
|
2013-02-27 03:34:08 +08:00
|
|
|
M6(); // expected-warning {{ignoring return value}}
|
|
|
|
M7(); // no warning
|
2012-10-24 07:19:32 +08:00
|
|
|
}
|
2013-01-17 10:06:08 +08:00
|
|
|
#undef NOP
|
2012-10-24 09:14:28 +08:00
|
|
|
#undef M1
|
|
|
|
#undef M2
|
2013-01-17 10:06:08 +08:00
|
|
|
#undef M3
|
|
|
|
#undef M4
|
|
|
|
#undef M5
|
2013-02-27 03:34:08 +08:00
|
|
|
#undef M6
|
|
|
|
#undef M7
|
Tweak how -Wunused-value interacts with macros
1. Make the warning more strict in C mode. r172696 added code to suppress
warnings from macro expansions in system headers, which checks
`SourceMgr.isMacroBodyExpansion(E->IgnoreParens()->getExprLoc())`. Consider
this snippet:
#define FOO(x) (x)
void f(int a) {
FOO(a);
}
In C, the line `FOO(a)` is an `ImplicitCastExpr(ParenExpr(DeclRefExpr))`,
while it's just a `ParenExpr(DeclRefExpr)` in C++. So in C++,
`E->IgnoreParens()` returns the `DeclRefExpr` and the check tests the
SourceLoc of `a`. In C, the `ImplicitCastExpr` has the effect of checking the
SourceLoc of `FOO`, which is a macro body expansion, which causes the
diagnostic to be skipped. It looks unintentional that clang does different
things for C and C++ here, so use `IgnoreParenImpCasts` instead of
`IgnoreParens` here. This has the effect of the warning firing more often
than previously in C code – it now fires as often as it fires in C++ code.
2. Suppress the warning if it would warn on `UNREFERENCED_PARAMETER`.
`UNREFERENCED_PARAMETER` is a commonly used macro on Windows and it happens
to uselessly trigger -Wunused-value. As discussed in the thread
"rfc: winnt.h's UNREFERENCED_PARAMETER() vs clang's -Wunused-value" on
cfe-dev, fix this by special-casing this specific macro. (This costs a string
comparison and some fast-path lexing per warning, but the warning is emitted
rarely. It fires once in Windows.h itself, so this code runs at least once
per TU including Windows.h, but it doesn't run hundreds of times.)
http://reviews.llvm.org/D13969
llvm-svn: 251441
2015-10-28 03:47:40 +08:00
|
|
|
|
|
|
|
#define UNREFERENCED_PARAMETER(x) (x)
|
|
|
|
|
|
|
|
void unused_parm(int a) {
|
|
|
|
// Don't warn if the warning is introduced by a macro that's spelled
|
|
|
|
// UNREFERENCED_PARAMETER, as that's a commonly used macro in Windows headers.
|
|
|
|
UNREFERENCED_PARAMETER(a);
|
|
|
|
}
|