2012-11-13 07:48:05 +08:00
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
2011-02-21 08:56:56 +08:00
int f ( ) __attribute__ ( ( warn_unused_result ) ) ;
struct S {
void t ( ) const ;
} ;
S g1 ( ) __attribute__ ( ( warn_unused_result ) ) ;
S * g2 ( ) __attribute__ ( ( warn_unused_result ) ) ;
S & g3 ( ) __attribute__ ( ( warn_unused_result ) ) ;
void test ( ) {
f ( ) ; // expected-warning {{ignoring return value}}
g1 ( ) ; // expected-warning {{ignoring return value}}
g2 ( ) ; // expected-warning {{ignoring return value}}
g3 ( ) ; // expected-warning {{ignoring return value}}
( void ) f ( ) ;
( void ) g1 ( ) ;
( void ) g2 ( ) ;
( void ) g3 ( ) ;
if ( f ( ) = = 0 ) return ;
g1 ( ) . t ( ) ;
g2 ( ) - > t ( ) ;
g3 ( ) . t ( ) ;
int i = f ( ) ;
S s1 = g1 ( ) ;
S * s2 = g2 ( ) ;
S & s3 = g3 ( ) ;
const S & s4 = g1 ( ) ;
}
struct X {
int foo ( ) __attribute__ ( ( warn_unused_result ) ) ;
} ;
void bah ( ) {
X x , * x2 ;
x . foo ( ) ; // expected-warning {{ignoring return value}}
x2 - > foo ( ) ; // expected-warning {{ignoring return value}}
}
2012-11-13 07:48:05 +08:00
namespace warn_unused_CXX11 {
2015-04-10 03:43:04 +08:00
class Status ;
class Foo {
public :
Status doStuff ( ) ;
} ;
2012-11-13 08:18:47 +08:00
struct [[clang::warn_unused_result]] Status {
2012-11-13 07:48:05 +08:00
bool ok ( ) const ;
2012-11-14 05:23:31 +08:00
Status & operator = ( const Status & x ) ;
inline void Update ( const Status & new_status ) {
if ( ok ( ) ) {
* this = new_status ; //no-warning
}
}
2012-11-13 07:48:05 +08:00
} ;
Status DoSomething ( ) ;
Status & DoSomethingElse ( ) ;
Status * DoAnotherThing ( ) ;
Status * * DoYetAnotherThing ( ) ;
void lazy ( ) {
Status s = DoSomething ( ) ;
if ( ! s . ok ( ) ) return ;
Status & rs = DoSomethingElse ( ) ;
if ( ! rs . ok ( ) ) return ;
Status * ps = DoAnotherThing ( ) ;
if ( ! ps - > ok ( ) ) return ;
Status * * pps = DoYetAnotherThing ( ) ;
if ( ! ( * pps ) - > ok ( ) ) return ;
( void ) DoSomething ( ) ;
( void ) DoSomethingElse ( ) ;
( void ) DoAnotherThing ( ) ;
( void ) DoYetAnotherThing ( ) ;
DoSomething ( ) ; // expected-warning {{ignoring return value}}
2015-04-10 03:43:04 +08:00
DoSomethingElse ( ) ;
DoAnotherThing ( ) ;
2012-11-13 07:48:05 +08:00
DoYetAnotherThing ( ) ;
}
2015-04-10 03:43:04 +08:00
template < typename T >
class [[clang::warn_unused_result]] StatusOr {
} ;
StatusOr < int > doit ( ) ;
void test ( ) {
Foo f ;
f . doStuff ( ) ; // expected-warning {{ignoring return value}}
doit ( ) ; // expected-warning {{ignoring return value}}
auto func = [ ] ( ) { return Status ( ) ; } ;
func ( ) ; // expected-warning {{ignoring return value}}
}
2012-11-13 07:48:05 +08:00
}
2013-10-17 00:21:04 +08:00
namespace PR17587 {
struct [[clang::warn_unused_result]] Status ;
struct Foo {
Status Bar ( ) ;
} ;
struct Status { } ;
void Bar ( ) {
Foo f ;
f . Bar ( ) ; // expected-warning {{ignoring return value}}
} ;
}
2014-10-17 04:13:28 +08:00
namespace PR18571 {
// Unevaluated contexts should not trigger unused result warnings.
template < typename T >
auto foo ( T ) - > decltype ( f ( ) , bool ( ) ) { // Should not warn.
return true ;
}
void g ( ) {
foo ( 1 ) ;
}
}
namespace std {
class type_info { } ;
}
namespace {
// The typeid expression operand is evaluated only when the expression type is
// a glvalue of polymorphic class type.
struct B {
virtual void f ( ) { }
} ;
struct D : B {
void f ( ) override { }
} ;
struct C { } ;
void g ( ) {
// The typeid expression operand is evaluated only when the expression type is
// a glvalue of polymorphic class type; otherwise the expression operand is not
// evaluated and should not trigger a diagnostic.
D d ;
C c ;
( void ) typeid ( f ( ) , c ) ; // Should not warn.
2014-12-18 05:57:17 +08:00
( void ) typeid ( f ( ) , d ) ; // expected-warning {{ignoring return value}} expected-warning {{expression with side effects will be evaluated despite being used as an operand to 'typeid'}}
2014-10-17 04:13:28 +08:00
// The sizeof expression operand is never evaluated.
( void ) sizeof ( f ( ) , c ) ; // Should not warn.
// The noexcept expression operand is never evaluated.
( void ) noexcept ( f ( ) , false ) ; // Should not warn.
}
}
2017-04-20 05:24:55 +08:00
namespace {
// C++ Methods should warn even in their own class.
struct [[clang::warn_unused_result]] S {
S DoThing ( ) { return { } ; } ;
S operator + + ( int ) { return { } ; } ;
S operator - - ( int ) { return { } ; } ;
// Improperly written prefix.
S operator + + ( ) { return { } ; } ;
S operator - - ( ) { return { } ; } ;
} ;
struct [[clang::warn_unused_result]] P {
P DoThing ( ) { return { } ; } ;
} ;
P operator + + ( const P & , int ) { return { } ; } ;
P operator - - ( const P & , int ) { return { } ; } ;
// Improperly written prefix.
P operator + + ( const P & ) { return { } ; } ;
P operator - - ( const P & ) { return { } ; } ;
void f ( ) {
S s ;
P p ;
s . DoThing ( ) ; // expected-warning {{ignoring return value}}
p . DoThing ( ) ; // expected-warning {{ignoring return value}}
// Only postfix is expected to warn when written correctly.
s + + ; // expected-warning {{ignoring return value}}
s - - ; // expected-warning {{ignoring return value}}
p + + ; // expected-warning {{ignoring return value}}
p - - ; // expected-warning {{ignoring return value}}
// Improperly written prefix operators should still warn.
+ + s ; // expected-warning {{ignoring return value}}
- - s ; // expected-warning {{ignoring return value}}
+ + p ; // expected-warning {{ignoring return value}}
- - p ; // expected-warning {{ignoring return value}}
// Silencing the warning by cast to void still works.
( void ) s . DoThing ( ) ;
( void ) s + + ;
( void ) p + + ;
( void ) + + s ;
( void ) + + p ;
}
} // namespace