2013-10-18 06:21:03 +08:00
// RUN: %clang_cc1 -fsyntax-only -verify -Wconsumed -fcxx-exceptions -std=c++11 %s
2013-08-13 05:20:55 +08:00
2013-10-05 05:28:06 +08:00
// TODO: Switch to using macros for the expected warnings.
# define CALLABLE_WHEN(...) __attribute__ ((callable_when(__VA_ARGS__)))
# define CONSUMABLE(state) __attribute__ ((consumable(state)))
2013-10-18 07:23:53 +08:00
# define PARAM_TYPESTATE(state) __attribute__ ((param_typestate(state)))
2013-10-05 05:28:06 +08:00
# define RETURN_TYPESTATE(state) __attribute__ ((return_typestate(state)))
2013-10-18 07:23:53 +08:00
# define SET_TYPESTATE(state) __attribute__ ((set_typestate(state)))
2013-10-12 06:30:48 +08:00
# define TESTS_TYPESTATE(state) __attribute__ ((tests_typestate(state)))
2013-08-13 05:20:55 +08:00
typedef decltype ( nullptr ) nullptr_t ;
template < typename T >
2013-09-06 09:28:43 +08:00
class CONSUMABLE ( unconsumed ) ConsumableClass {
2013-08-13 05:20:55 +08:00
T var ;
2013-10-12 05:55:33 +08:00
public :
2013-08-30 01:26:57 +08:00
ConsumableClass ( ) ;
2013-09-04 04:11:38 +08:00
ConsumableClass ( nullptr_t p ) RETURN_TYPESTATE ( consumed ) ;
ConsumableClass ( T val ) RETURN_TYPESTATE ( unconsumed ) ;
2013-09-06 09:28:43 +08:00
ConsumableClass ( ConsumableClass < T > & other ) ;
ConsumableClass ( ConsumableClass < T > & & other ) ;
2013-08-13 05:20:55 +08:00
2013-08-24 02:40:39 +08:00
ConsumableClass < T > & operator = ( ConsumableClass < T > & other ) ;
ConsumableClass < T > & operator = ( ConsumableClass < T > & & other ) ;
2013-10-12 07:03:26 +08:00
ConsumableClass < T > & operator = ( nullptr_t ) SET_TYPESTATE ( consumed ) ;
2013-08-13 05:20:55 +08:00
template < typename U >
2013-08-24 02:40:39 +08:00
ConsumableClass < T > & operator = ( ConsumableClass < U > & other ) ;
2013-08-13 05:20:55 +08:00
template < typename U >
2013-08-24 02:40:39 +08:00
ConsumableClass < T > & operator = ( ConsumableClass < U > & & other ) ;
2013-08-13 05:20:55 +08:00
2013-10-12 07:03:26 +08:00
void operator ( ) ( int a ) SET_TYPESTATE ( consumed ) ;
2013-10-05 05:28:06 +08:00
void operator * ( ) const CALLABLE_WHEN ( " unconsumed " ) ;
void unconsumedCall ( ) const CALLABLE_WHEN ( " unconsumed " ) ;
void callableWhenUnknown ( ) const CALLABLE_WHEN ( " unconsumed " , " unknown " ) ;
2013-08-13 05:20:55 +08:00
2013-10-12 06:30:48 +08:00
bool isValid ( ) const TESTS_TYPESTATE ( unconsumed ) ;
operator bool ( ) const TESTS_TYPESTATE ( unconsumed ) ;
bool operator ! = ( nullptr_t ) const TESTS_TYPESTATE ( unconsumed ) ;
bool operator = = ( nullptr_t ) const TESTS_TYPESTATE ( consumed ) ;
2013-08-13 05:20:55 +08:00
2013-08-30 01:26:57 +08:00
void constCall ( ) const ;
void nonconstCall ( ) ;
2013-08-13 05:20:55 +08:00
2013-10-12 07:03:26 +08:00
void consume ( ) SET_TYPESTATE ( consumed ) ;
void unconsume ( ) SET_TYPESTATE ( unconsumed ) ;
2013-08-13 05:20:55 +08:00
} ;
2013-10-12 05:55:33 +08:00
class CONSUMABLE ( unconsumed ) DestructorTester {
public :
DestructorTester ( int ) ;
void operator * ( ) ;
~ DestructorTester ( ) CALLABLE_WHEN ( " consumed " ) ;
} ;
2013-08-24 02:40:39 +08:00
void baf0 ( const ConsumableClass < int > var ) ;
void baf1 ( const ConsumableClass < int > & var ) ;
void baf2 ( const ConsumableClass < int > * var ) ;
2013-08-13 05:20:55 +08:00
2013-10-05 05:28:06 +08:00
void baf3 ( ConsumableClass < int > & var ) ;
void baf4 ( ConsumableClass < int > * var ) ;
void baf5 ( ConsumableClass < int > & & var ) ;
2013-08-13 05:20:55 +08:00
2013-09-04 04:11:38 +08:00
ConsumableClass < int > returnsUnconsumed ( ) {
return ConsumableClass < int > ( ) ; // expected-warning {{return value not in expected state; expected 'unconsumed', observed 'consumed'}}
}
ConsumableClass < int > returnsConsumed ( ) RETURN_TYPESTATE ( consumed ) ;
ConsumableClass < int > returnsConsumed ( ) {
return ConsumableClass < int > ( ) ;
}
2013-10-05 05:28:06 +08:00
ConsumableClass < int > returnsUnknown ( ) RETURN_TYPESTATE ( unknown ) ;
2013-08-30 01:26:57 +08:00
void testInitialization ( ) {
2013-08-24 02:40:39 +08:00
ConsumableClass < int > var0 ;
ConsumableClass < int > var1 = ConsumableClass < int > ( ) ;
2013-08-13 05:20:55 +08:00
2013-08-24 02:40:39 +08:00
var0 = ConsumableClass < int > ( ) ;
2013-08-13 05:20:55 +08:00
2013-10-05 05:28:06 +08:00
* var0 ; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
* var1 ; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
2013-08-13 05:20:55 +08:00
if ( var0 . isValid ( ) ) {
* var0 ;
2013-08-30 01:26:57 +08:00
* var1 ;
2013-08-13 05:20:55 +08:00
} else {
2013-10-05 05:28:06 +08:00
* var0 ; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
2013-08-13 05:20:55 +08:00
}
}
2013-10-12 05:55:33 +08:00
void testDestruction ( ) {
DestructorTester D0 ( 42 ) , D1 ( 42 ) ;
* D0 ;
* D1 ;
D0 . ~ DestructorTester ( ) ; // expected-warning {{invalid invocation of method '~DestructorTester' on object 'D0' while it is in the 'unconsumed' state}}
return ; // expected-warning {{invalid invocation of method '~DestructorTester' on object 'D0' while it is in the 'unconsumed' state}} expected-warning {{invalid invocation of method '~DestructorTester' on object 'D1' while it is in the 'unconsumed' state}}
}
2013-08-24 02:40:39 +08:00
void testTempValue ( ) {
2013-10-05 05:28:06 +08:00
* ConsumableClass < int > ( ) ; // expected-warning {{invalid invocation of method 'operator*' on a temporary object while it is in the 'consumed' state}}
2013-08-23 04:44:47 +08:00
}
2013-08-30 01:26:57 +08:00
void testSimpleRValueRefs ( ) {
2013-08-24 02:40:39 +08:00
ConsumableClass < int > var0 ;
ConsumableClass < int > var1 ( 42 ) ;
2013-08-13 05:20:55 +08:00
2013-10-05 05:28:06 +08:00
* var0 ; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
2013-08-13 05:20:55 +08:00
* var1 ;
2013-08-24 02:40:39 +08:00
var0 = static_cast < ConsumableClass < int > & & > ( var1 ) ;
2013-08-13 05:20:55 +08:00
* var0 ;
2013-10-05 05:28:06 +08:00
* var1 ; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
2013-08-13 05:20:55 +08:00
}
2013-08-30 01:26:57 +08:00
void testIfStmt ( ) {
2013-08-24 02:40:39 +08:00
ConsumableClass < int > var ;
2013-08-13 05:20:55 +08:00
if ( var . isValid ( ) ) {
2013-08-30 01:26:57 +08:00
* var ;
2013-08-13 05:20:55 +08:00
} else {
2013-10-05 05:28:06 +08:00
* var ; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}}
2013-08-13 05:20:55 +08:00
}
if ( ! var . isValid ( ) ) {
2013-10-05 05:28:06 +08:00
* var ; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}}
2013-08-13 05:20:55 +08:00
} else {
* var ;
}
if ( var ) {
// Empty
} else {
2013-10-05 05:28:06 +08:00
* var ; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}}
2013-08-13 05:20:55 +08:00
}
2013-08-23 04:44:47 +08:00
if ( var ! = nullptr ) {
// Empty
} else {
2013-10-05 05:28:06 +08:00
* var ; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}}
2013-08-23 04:44:47 +08:00
}
2013-10-12 06:30:48 +08:00
if ( var = = nullptr ) {
* var ; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}}
} else {
// Empty
}
2013-08-13 05:20:55 +08:00
}
2013-10-05 05:28:06 +08:00
void testComplexConditionals0 ( ) {
2013-08-30 01:26:57 +08:00
ConsumableClass < int > var0 , var1 , var2 ;
if ( var0 & & var1 ) {
* var0 ;
* var1 ;
} else {
2013-10-05 05:28:06 +08:00
* var0 ; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
* var1 ; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
2013-08-30 01:26:57 +08:00
}
if ( var0 | | var1 ) {
* var0 ;
* var1 ;
} else {
2013-10-05 05:28:06 +08:00
* var0 ; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
* var1 ; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
2013-08-30 01:26:57 +08:00
}
if ( var0 & & ! var1 ) {
* var0 ;
* var1 ;
} else {
2013-10-05 05:28:06 +08:00
* var0 ; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
* var1 ; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
2013-08-30 01:26:57 +08:00
}
if ( var0 | | ! var1 ) {
2013-10-05 05:28:06 +08:00
* var0 ; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
* var1 ; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
2013-08-30 01:26:57 +08:00
} else {
* var0 ;
* var1 ;
}
if ( ! var0 & & ! var1 ) {
2013-10-05 05:28:06 +08:00
* var0 ; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
* var1 ; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
2013-08-30 01:26:57 +08:00
} else {
* var0 ;
* var1 ;
}
if ( ! var0 | | ! var1 ) {
2013-10-05 05:28:06 +08:00
* var0 ; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
* var1 ; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
2013-08-30 01:26:57 +08:00
} else {
* var0 ;
* var1 ;
}
if ( ! ( var0 & & var1 ) ) {
2013-10-05 05:28:06 +08:00
* var0 ; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
* var1 ; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
2013-08-30 01:26:57 +08:00
} else {
* var0 ;
* var1 ;
}
if ( ! ( var0 | | var1 ) ) {
2013-10-05 05:28:06 +08:00
* var0 ; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
* var1 ; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
2013-08-30 01:26:57 +08:00
} else {
* var0 ;
* var1 ;
}
if ( var0 & & var1 & & var2 ) {
* var0 ;
* var1 ;
* var2 ;
} else {
2013-10-05 05:28:06 +08:00
* var0 ; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
* var1 ; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
* var2 ; // expected-warning {{invalid invocation of method 'operator*' on object 'var2' while it is in the 'consumed' state}}
2013-08-30 01:26:57 +08:00
}
#if 0
// FIXME: Get this test to pass.
if ( var0 | | var1 | | var2 ) {
* var0 ;
* var1 ;
* var2 ;
} else {
2013-10-05 05:28:06 +08:00
* var0 ; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
* var1 ; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
* var2 ; // expected-warning {{invalid invocation of method 'operator*' on object 'var2' while it is in the 'consumed' state}}
}
# endif
}
void testComplexConditionals1 ( ) {
ConsumableClass < int > var0 , var1 , var2 ;
// Coerce all variables into the unknown state.
baf3 ( var0 ) ;
baf3 ( var1 ) ;
baf3 ( var2 ) ;
if ( var0 & & var1 ) {
* var0 ;
* var1 ;
} else {
* var0 ; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}}
* var1 ; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}}
}
if ( var0 | | var1 ) {
* var0 ; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}}
* var1 ; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}}
} else {
* var0 ; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
* var1 ; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
}
if ( var0 & & ! var1 ) {
* var0 ;
* var1 ; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
} else {
* var0 ; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}}
* var1 ; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}}
}
if ( var0 | | ! var1 ) {
* var0 ; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}}
* var1 ; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}}
} else {
* var0 ; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
* var1 ;
}
if ( ! var0 & & ! var1 ) {
* var0 ; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
* var1 ; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
} else {
* var0 ; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}}
* var1 ; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}}
}
if ( ! ( var0 | | var1 ) ) {
* var0 ; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
* var1 ; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
} else {
* var0 ; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}}
* var1 ; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}}
}
if ( ! var0 | | ! var1 ) {
* var0 ; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}}
* var1 ; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}}
} else {
* var0 ;
* var1 ;
}
if ( ! ( var0 & & var1 ) ) {
* var0 ; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}}
* var1 ; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}}
} else {
* var0 ;
* var1 ;
}
if ( var0 & & var1 & & var2 ) {
* var0 ;
* var1 ;
* var2 ;
} else {
* var0 ; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}}
* var1 ; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}}
* var2 ; // expected-warning {{invalid invocation of method 'operator*' on object 'var2' while it is in the 'unknown' state}}
}
#if 0
// FIXME: Get this test to pass.
if ( var0 | | var1 | | var2 ) {
* var0 ; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}}
* var1 ; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}}
* var2 ; // expected-warning {{invalid invocation of method 'operator*' on object 'var2' while it is in the 'unknown' state}}
} else {
* var0 ; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
* var1 ; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
* var2 ; // expected-warning {{invalid invocation of method 'operator*' on object 'var2' while it is in the 'consumed' state}}
2013-08-30 01:26:57 +08:00
}
# endif
}
void testStateChangeInBranch ( ) {
ConsumableClass < int > var ;
// Make var enter the 'unknown' state.
2013-10-05 05:28:06 +08:00
baf3 ( var ) ;
2013-08-30 01:26:57 +08:00
if ( ! var ) {
var = ConsumableClass < int > ( 42 ) ;
}
* var ;
}
2013-08-30 06:36:05 +08:00
void testFunctionParam ( ConsumableClass < int > param ) {
if ( param . isValid ( ) ) {
* param ;
} else {
2013-09-06 09:28:43 +08:00
* param ;
2013-08-30 06:36:05 +08:00
}
param = nullptr ;
* param ; // expected-warning {{invocation of method 'operator*' on object 'param' while it is in the 'consumed' state}}
}
2013-10-18 06:53:04 +08:00
void testParamReturnTypestateCallee ( bool cond , ConsumableClass < int > & Param RETURN_TYPESTATE ( unconsumed ) ) { // expected-warning {{parameter 'Param' not in expected state when the function returns: expected 'unconsumed', observed 'consumed'}}
if ( cond ) {
Param . consume ( ) ;
return ; // expected-warning {{parameter 'Param' not in expected state when the function returns: expected 'unconsumed', observed 'consumed'}}
}
Param . consume ( ) ;
}
void testParamReturnTypestateCaller ( ) {
ConsumableClass < int > var ;
testParamReturnTypestateCallee ( true , var ) ;
* var ;
}
2013-10-18 07:23:53 +08:00
void testParamTypestateCallee ( ConsumableClass < int > Param0 PARAM_TYPESTATE ( consumed ) ,
ConsumableClass < int > & Param1 PARAM_TYPESTATE ( consumed ) ) {
* Param0 ; // expected-warning {{invalid invocation of method 'operator*' on object 'Param0' while it is in the 'consumed' state}}
* Param1 ; // expected-warning {{invalid invocation of method 'operator*' on object 'Param1' while it is in the 'consumed' state}}
}
void testParamTypestateCaller ( ) {
ConsumableClass < int > Var0 , Var1 ( 42 ) ;
testParamTypestateCallee ( Var0 , Var1 ) ; // expected-warning {{argument not in expected state; expected 'consumed', observed 'unconsumed'}}
}
2013-08-30 01:26:57 +08:00
void testCallingConventions ( ) {
2013-08-24 02:40:39 +08:00
ConsumableClass < int > var ( 42 ) ;
2013-08-13 05:20:55 +08:00
baf0 ( var ) ;
* var ;
baf1 ( var ) ;
* var ;
baf2 ( & var ) ;
* var ;
2013-10-05 05:28:06 +08:00
baf3 ( var ) ;
* var ; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'unknown' state}}
var = ConsumableClass < int > ( 42 ) ;
baf4 ( & var ) ;
* var ; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'unknown' state}}
var = ConsumableClass < int > ( 42 ) ;
baf5 ( static_cast < ConsumableClass < int > & & > ( var ) ) ;
* var ; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}}
}
void testConstAndNonConstMemberFunctions ( ) {
ConsumableClass < int > var ( 42 ) ;
var . constCall ( ) ;
* var ;
var . nonconstCall ( ) ;
* var ;
}
void testFunctionParam0 ( ConsumableClass < int > param ) {
* param ;
}
void testFunctionParam1 ( ConsumableClass < int > & param ) {
* param ; // expected-warning {{invalid invocation of method 'operator*' on object 'param' while it is in the 'unknown' state}}
2013-09-04 04:11:38 +08:00
}
void testReturnStates ( ) {
ConsumableClass < int > var ;
var = returnsUnconsumed ( ) ;
* var ;
var = returnsConsumed ( ) ;
2013-10-05 05:28:06 +08:00
* var ; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}}
}
void testCallableWhen ( ) {
ConsumableClass < int > var ( 42 ) ;
* var ;
baf3 ( var ) ;
var . callableWhenUnknown ( ) ;
2013-08-13 05:20:55 +08:00
}
2013-08-30 01:26:57 +08:00
void testMoveAsignmentish ( ) {
2013-08-24 02:40:39 +08:00
ConsumableClass < int > var0 ;
ConsumableClass < long > var1 ( 42 ) ;
2013-08-13 05:20:55 +08:00
2013-10-05 05:28:06 +08:00
* var0 ; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
2013-08-13 05:20:55 +08:00
* var1 ;
2013-08-24 02:40:39 +08:00
var0 = static_cast < ConsumableClass < long > & & > ( var1 ) ;
2013-08-13 05:20:55 +08:00
* var0 ;
2013-10-05 05:28:06 +08:00
* var1 ; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
2013-08-30 05:17:25 +08:00
var1 = ConsumableClass < long > ( 42 ) ;
var1 = nullptr ;
2013-10-05 05:28:06 +08:00
* var1 ; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
2013-08-13 05:20:55 +08:00
}
2013-08-30 01:26:57 +08:00
void testConditionalMerge ( ) {
2013-08-24 02:40:39 +08:00
ConsumableClass < int > var ;
2013-08-13 05:20:55 +08:00
if ( var . isValid ( ) ) {
// Empty
}
2013-10-05 05:28:06 +08:00
* var ; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}}
2013-08-13 05:20:55 +08:00
if ( var . isValid ( ) ) {
// Empty
} else {
// Empty
}
2013-10-05 05:28:06 +08:00
* var ; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}}
2013-08-13 05:20:55 +08:00
}
2013-10-12 07:03:26 +08:00
void testSetTypestate ( ) {
2013-08-24 02:40:39 +08:00
ConsumableClass < int > var ( 42 ) ;
2013-08-13 05:20:55 +08:00
* var ;
var . consume ( ) ;
2013-10-05 05:28:06 +08:00
* var ; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}}
2013-10-12 07:03:26 +08:00
var . unconsume ( ) ;
* var ;
2013-08-13 05:20:55 +08:00
}
2013-10-12 07:03:26 +08:00
void testConsumes0 ( ) {
2013-08-24 02:40:39 +08:00
ConsumableClass < int > var ( nullptr ) ;
2013-08-13 05:20:55 +08:00
2013-10-05 05:28:06 +08:00
* var ; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}}
2013-08-13 05:20:55 +08:00
}
2013-10-12 07:03:26 +08:00
void testConsumes1 ( ) {
2013-08-24 02:40:39 +08:00
ConsumableClass < int > var ( 42 ) ;
2013-08-23 04:44:47 +08:00
var . unconsumedCall ( ) ;
var ( 6 ) ;
2013-10-05 05:28:06 +08:00
var . unconsumedCall ( ) ; // expected-warning {{invalid invocation of method 'unconsumedCall' on object 'var' while it is in the 'consumed' state}}
2013-08-23 04:44:47 +08:00
}
2013-10-05 05:28:06 +08:00
void testUnreachableBlock ( ) {
2013-08-30 01:26:57 +08:00
ConsumableClass < int > var ( 42 ) ;
if ( var ) {
* var ;
} else {
* var ;
}
* var ;
}
2013-10-10 02:30:24 +08:00
void testForLoop1 ( ) {
ConsumableClass < int > var0 , var1 ( 42 ) ;
2013-08-13 05:20:55 +08:00
2013-10-10 02:30:24 +08:00
for ( int i = 0 ; i < 10 ; + + i ) { // expected-warning {{state of variable 'var1' must match at the entry and exit of loop}}
* var0 ; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
* var1 ;
var1 . consume ( ) ;
* var1 ; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
2013-08-13 05:20:55 +08:00
}
2013-10-10 02:30:24 +08:00
* var0 ; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
2013-08-13 05:20:55 +08:00
}
2013-10-10 02:30:24 +08:00
void testWhileLoop1 ( ) {
int i = 10 ;
2013-08-13 05:20:55 +08:00
2013-10-10 02:30:24 +08:00
ConsumableClass < int > var0 , var1 ( 42 ) ;
2013-08-13 05:20:55 +08:00
2013-10-18 02:19:31 +08:00
while ( i - - > 0 ) { // expected-warning {{state of variable 'var1' must match at the entry and exit of loop}}
2013-10-10 02:30:24 +08:00
* var0 ; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
* var1 ;
var1 . consume ( ) ;
2013-10-18 02:19:31 +08:00
* var1 ; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
2013-08-13 05:20:55 +08:00
}
2013-10-10 02:30:24 +08:00
* var0 ; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
2013-08-13 05:20:55 +08:00
}
2013-10-18 02:19:31 +08:00
namespace ContinueICETest {
bool cond1 ( ) ;
bool cond2 ( ) ;
static void foo1 ( ) {
while ( cond1 ( ) ) {
if ( cond2 ( ) )
continue ;
}
}
static void foo2 ( ) {
while ( true ) {
if ( false )
continue ;
}
}
2013-10-18 06:21:03 +08:00
class runtime_error
{
public :
virtual ~ runtime_error ( ) ;
} ;
void read ( bool sf ) {
while ( sf ) {
if ( sf ) throw runtime_error ( ) ;
}
}
2013-10-18 02:19:31 +08:00
} // end namespace ContinueICETest