Home | History | Annotate | Download | only in SemaCXX
      1 // RUN: %clang_cc1 -fsyntax-only -verify -Wconsumed -fcxx-exceptions -std=c++11 %s
      2 
      3 // TODO: Switch to using macros for the expected warnings.
      4 
      5 #define CALLABLE_WHEN(...)      __attribute__ ((callable_when(__VA_ARGS__)))
      6 #define CONSUMABLE(state)       __attribute__ ((consumable(state)))
      7 #define PARAM_TYPESTATE(state)  __attribute__ ((param_typestate(state)))
      8 #define RETURN_TYPESTATE(state) __attribute__ ((return_typestate(state)))
      9 #define SET_TYPESTATE(state)    __attribute__ ((set_typestate(state)))
     10 #define TEST_TYPESTATE(state)   __attribute__ ((test_typestate(state)))
     11 
     12 typedef decltype(nullptr) nullptr_t;
     13 
     14 template <typename T>
     15 class CONSUMABLE(unconsumed) ConsumableClass {
     16   T var;
     17 
     18 public:
     19   ConsumableClass();
     20   ConsumableClass(nullptr_t p) RETURN_TYPESTATE(consumed);
     21   ConsumableClass(T val) RETURN_TYPESTATE(unconsumed);
     22   ConsumableClass(ConsumableClass<T> &other);
     23   ConsumableClass(ConsumableClass<T> &&other);
     24 
     25   ConsumableClass<T>& operator=(ConsumableClass<T>  &other);
     26   ConsumableClass<T>& operator=(ConsumableClass<T> &&other);
     27   ConsumableClass<T>& operator=(nullptr_t) SET_TYPESTATE(consumed);
     28 
     29   template <typename U>
     30   ConsumableClass<T>& operator=(ConsumableClass<U>  &other);
     31 
     32   template <typename U>
     33   ConsumableClass<T>& operator=(ConsumableClass<U> &&other);
     34 
     35   void operator()(int a) SET_TYPESTATE(consumed);
     36   void operator*() const CALLABLE_WHEN("unconsumed");
     37   void unconsumedCall() const CALLABLE_WHEN("unconsumed");
     38   void callableWhenUnknown() const CALLABLE_WHEN("unconsumed", "unknown");
     39 
     40   bool isValid() const TEST_TYPESTATE(unconsumed);
     41   operator bool() const TEST_TYPESTATE(unconsumed);
     42   bool operator!=(nullptr_t) const TEST_TYPESTATE(unconsumed);
     43   bool operator==(nullptr_t) const TEST_TYPESTATE(consumed);
     44 
     45   void constCall() const;
     46   void nonconstCall();
     47 
     48   void consume() SET_TYPESTATE(consumed);
     49   void unconsume() SET_TYPESTATE(unconsumed);
     50 };
     51 
     52 class CONSUMABLE(unconsumed) DestructorTester {
     53 public:
     54   DestructorTester();
     55   DestructorTester(int);
     56 
     57   void operator*() CALLABLE_WHEN("unconsumed");
     58 
     59   ~DestructorTester() CALLABLE_WHEN("consumed");
     60 };
     61 
     62 void baf0(const ConsumableClass<int>  var);
     63 void baf1(const ConsumableClass<int> &var);
     64 void baf2(const ConsumableClass<int> *var);
     65 
     66 void baf3(ConsumableClass<int>   var);
     67 void baf4(ConsumableClass<int>  &var);
     68 void baf5(ConsumableClass<int>  *var);
     69 void baf6(ConsumableClass<int> &&var);
     70 
     71 ConsumableClass<int> returnsUnconsumed() {
     72   return ConsumableClass<int>(); // expected-warning {{return value not in expected state; expected 'unconsumed', observed 'consumed'}}
     73 }
     74 
     75 ConsumableClass<int> returnsConsumed() RETURN_TYPESTATE(consumed);
     76 ConsumableClass<int> returnsConsumed() {
     77   return ConsumableClass<int>();
     78 }
     79 
     80 ConsumableClass<int> returnsUnknown() RETURN_TYPESTATE(unknown);
     81 
     82 void testInitialization() {
     83   ConsumableClass<int> var0;
     84   ConsumableClass<int> var1 = ConsumableClass<int>();
     85   ConsumableClass<int> var2(42);
     86   ConsumableClass<int> var3(var2);  // copy constructor
     87   ConsumableClass<int> var4(var0);  // copy consumed value
     88 
     89   *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
     90   *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
     91   *var2;
     92   *var3;
     93   *var4; // expected-warning {{invalid invocation of method 'operator*' on object 'var4' while it is in the 'consumed' state}}
     94 
     95   var0 = ConsumableClass<int>(42);
     96   *var0;
     97 
     98   var0 = var1;
     99   *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
    100 
    101   if (var0.isValid()) {
    102     *var0;
    103     *var1;
    104 
    105   } else {
    106     *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
    107   }
    108 }
    109 
    110 void testDestruction() {
    111   DestructorTester D0(42), D1(42), D2;
    112 
    113   *D0;
    114   *D1;
    115   *D2; // expected-warning {{invalid invocation of method 'operator*' on object 'D2' while it is in the 'consumed' state}}
    116 
    117   D0.~DestructorTester(); // expected-warning {{invalid invocation of method '~DestructorTester' on object 'D0' while it is in the 'unconsumed' state}}
    118 
    119   return; // expected-warning {{invalid invocation of method '~DestructorTester' on object 'D0' while it is in the 'unconsumed' state}} \
    120              expected-warning {{invalid invocation of method '~DestructorTester' on object 'D1' while it is in the 'unconsumed' state}}
    121 }
    122 
    123 void testTempValue() {
    124   *ConsumableClass<int>(); // expected-warning {{invalid invocation of method 'operator*' on a temporary object while it is in the 'consumed' state}}
    125 }
    126 
    127 void testSimpleRValueRefs() {
    128   ConsumableClass<int> var0;
    129   ConsumableClass<int> var1(42);
    130 
    131   *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
    132   *var1;
    133 
    134   var0 = static_cast<ConsumableClass<int>&&>(var1);
    135 
    136   *var0;
    137   *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
    138 }
    139 
    140 void testIfStmt() {
    141   ConsumableClass<int> var;
    142 
    143   if (var.isValid()) {
    144     *var;
    145   } else {
    146     *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}}
    147   }
    148 
    149   if (!var.isValid()) {
    150     *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}}
    151   } else {
    152     *var;
    153   }
    154 
    155   if (var) {
    156     // Empty
    157   } else {
    158     *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}}
    159   }
    160 
    161   if (var != nullptr) {
    162     // Empty
    163   } else {
    164     *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}}
    165   }
    166 
    167   if (var == nullptr) {
    168     *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}}
    169   } else {
    170     // Empty
    171   }
    172 }
    173 
    174 void testComplexConditionals0() {
    175   ConsumableClass<int> var0, var1, var2;
    176 
    177   if (var0 && var1) {
    178     *var0;
    179     *var1;
    180 
    181   } else {
    182     *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
    183     *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
    184   }
    185 
    186   if (var0 || var1) {
    187     *var0;
    188     *var1;
    189 
    190   } else {
    191     *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
    192     *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
    193   }
    194 
    195   if (var0 && !var1) {
    196     *var0;
    197     *var1;
    198 
    199   } else {
    200     *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
    201     *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
    202   }
    203 
    204   if (var0 || !var1) {
    205     *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
    206     *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
    207 
    208   } else {
    209     *var0;
    210     *var1;
    211   }
    212 
    213   if (!var0 && !var1) {
    214     *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
    215     *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
    216 
    217   } else {
    218     *var0;
    219     *var1;
    220   }
    221 
    222   if (!var0 || !var1) {
    223     *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
    224     *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
    225 
    226   } else {
    227     *var0;
    228     *var1;
    229   }
    230 
    231   if (!(var0 && var1)) {
    232     *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
    233     *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
    234 
    235   } else {
    236     *var0;
    237     *var1;
    238   }
    239 
    240   if (!(var0 || var1)) {
    241     *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
    242     *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
    243 
    244   } else {
    245     *var0;
    246     *var1;
    247   }
    248 
    249   if (var0 && var1 && var2) {
    250     *var0;
    251     *var1;
    252     *var2;
    253 
    254   } else {
    255     *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
    256     *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
    257     *var2; // expected-warning {{invalid invocation of method 'operator*' on object 'var2' while it is in the 'consumed' state}}
    258   }
    259 
    260 #if 0
    261   // FIXME: Get this test to pass.
    262   if (var0 || var1 || var2) {
    263     *var0;
    264     *var1;
    265     *var2;
    266 
    267   } else {
    268     *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
    269     *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
    270     *var2; // expected-warning {{invalid invocation of method 'operator*' on object 'var2' while it is in the 'consumed' state}}
    271   }
    272 #endif
    273 }
    274 
    275 void testComplexConditionals1() {
    276   ConsumableClass<int> var0, var1, var2;
    277 
    278   // Coerce all variables into the unknown state.
    279   baf4(var0);
    280   baf4(var1);
    281   baf4(var2);
    282 
    283   if (var0 && var1) {
    284     *var0;
    285     *var1;
    286 
    287   } else {
    288     *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}}
    289     *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}}
    290   }
    291 
    292   if (var0 || var1) {
    293     *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}}
    294     *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}}
    295 
    296   } else {
    297     *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
    298     *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
    299   }
    300 
    301   if (var0 && !var1) {
    302     *var0;
    303     *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
    304 
    305   } else {
    306     *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}}
    307     *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}}
    308   }
    309 
    310   if (var0 || !var1) {
    311     *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}}
    312     *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}}
    313 
    314   } else {
    315     *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
    316     *var1;
    317   }
    318 
    319   if (!var0 && !var1) {
    320     *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
    321     *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
    322 
    323   } else {
    324     *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}}
    325     *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}}
    326   }
    327 
    328   if (!(var0 || var1)) {
    329     *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
    330     *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
    331 
    332   } else {
    333     *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}}
    334     *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}}
    335   }
    336 
    337   if (!var0 || !var1) {
    338     *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}}
    339     *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}}
    340 
    341   } else {
    342     *var0;
    343     *var1;
    344   }
    345 
    346   if (!(var0 && var1)) {
    347     *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}}
    348     *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}}
    349 
    350   } else {
    351     *var0;
    352     *var1;
    353   }
    354 
    355   if (var0 && var1 && var2) {
    356     *var0;
    357     *var1;
    358     *var2;
    359 
    360   } else {
    361     *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}}
    362     *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}}
    363     *var2; // expected-warning {{invalid invocation of method 'operator*' on object 'var2' while it is in the 'unknown' state}}
    364   }
    365 
    366 #if 0
    367   // FIXME: Get this test to pass.
    368   if (var0 || var1 || var2) {
    369     *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}}
    370     *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}}
    371     *var2; // expected-warning {{invalid invocation of method 'operator*' on object 'var2' while it is in the 'unknown' state}}
    372 
    373   } else {
    374     *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
    375     *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
    376     *var2; // expected-warning {{invalid invocation of method 'operator*' on object 'var2' while it is in the 'consumed' state}}
    377   }
    378 #endif
    379 }
    380 
    381 void testStateChangeInBranch() {
    382   ConsumableClass<int> var;
    383 
    384   // Make var enter the 'unknown' state.
    385   baf4(var);
    386 
    387   if (!var) {
    388     var = ConsumableClass<int>(42);
    389   }
    390 
    391   *var;
    392 }
    393 
    394 void testFunctionParam(ConsumableClass<int> param) {
    395 
    396   if (param.isValid()) {
    397     *param;
    398   } else {
    399     *param;
    400   }
    401 
    402   param = nullptr;
    403   *param; // expected-warning {{invocation of method 'operator*' on object 'param' while it is in the 'consumed' state}}
    404 }
    405 
    406 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'}}
    407 
    408   if (cond) {
    409     Param.consume();
    410     return; // expected-warning {{parameter 'Param' not in expected state when the function returns: expected 'unconsumed', observed 'consumed'}}
    411   }
    412 
    413   Param.consume();
    414 }
    415 
    416 void testParamReturnTypestateCaller() {
    417   ConsumableClass<int> var;
    418 
    419   testParamReturnTypestateCallee(true, var);
    420 
    421   *var;
    422 }
    423 
    424 void testParamTypestateCallee(ConsumableClass<int>  Param0 PARAM_TYPESTATE(consumed),
    425                               ConsumableClass<int> &Param1 PARAM_TYPESTATE(consumed)) {
    426 
    427   *Param0; // expected-warning {{invalid invocation of method 'operator*' on object 'Param0' while it is in the 'consumed' state}}
    428   *Param1; // expected-warning {{invalid invocation of method 'operator*' on object 'Param1' while it is in the 'consumed' state}}
    429 }
    430 
    431 void testParamTypestateCaller() {
    432   ConsumableClass<int> Var0, Var1(42);
    433 
    434   testParamTypestateCallee(Var0, Var1); // expected-warning {{argument not in expected state; expected 'consumed', observed 'unconsumed'}}
    435 }
    436 
    437 
    438 void consumeFunc(ConsumableClass<int> P PARAM_TYPESTATE(unconsumed));
    439 struct ParamTest {
    440   static void consumeFuncStatic(ConsumableClass<int> P PARAM_TYPESTATE(unconsumed));
    441   void consumeFuncMeth(ConsumableClass<int> P PARAM_TYPESTATE(unconsumed));
    442   void operator<<(ConsumableClass<int> P PARAM_TYPESTATE(unconsumed));
    443 };
    444 
    445 void operator>>(ParamTest& pt, ConsumableClass<int> P PARAM_TYPESTATE(unconsumed));
    446 
    447 
    448 void testFunctionParams() {
    449   // Make sure we handle the different kinds of functions.
    450   ConsumableClass<int> P;
    451 
    452   consumeFunc(P);                   // expected-warning {{argument not in expected state; expected 'unconsumed', observed 'consumed'}}
    453   ParamTest::consumeFuncStatic(P);  // expected-warning {{argument not in expected state; expected 'unconsumed', observed 'consumed'}}
    454   ParamTest pt;
    455   pt.consumeFuncMeth(P);            // expected-warning {{argument not in expected state; expected 'unconsumed', observed 'consumed'}}
    456   pt << P;                          // expected-warning {{argument not in expected state; expected 'unconsumed', observed 'consumed'}}
    457   pt >> P;                          // expected-warning {{argument not in expected state; expected 'unconsumed', observed 'consumed'}}
    458 }
    459 
    460 void baf3(ConsumableClass<int> var) {
    461   *var;
    462 }
    463 
    464 void baf4(ConsumableClass<int> &var) {
    465   *var;  // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'unknown' state}}
    466 }
    467 
    468 void baf6(ConsumableClass<int> &&var) {
    469   *var;
    470 }
    471 
    472 void testCallingConventions() {
    473   ConsumableClass<int> var(42);
    474 
    475   baf0(var);
    476   *var;
    477 
    478   baf1(var);
    479   *var;
    480 
    481   baf2(&var);
    482   *var;
    483 
    484   baf4(var);
    485   *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'unknown' state}}
    486 
    487   var = ConsumableClass<int>(42);
    488   baf5(&var);
    489   *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'unknown' state}}
    490 
    491   var = ConsumableClass<int>(42);
    492   baf6(static_cast<ConsumableClass<int>&&>(var));
    493   *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}}
    494 }
    495 
    496 void testConstAndNonConstMemberFunctions() {
    497   ConsumableClass<int> var(42);
    498 
    499   var.constCall();
    500   *var;
    501 
    502   var.nonconstCall();
    503   *var;
    504 }
    505 
    506 void testFunctionParam0(ConsumableClass<int> param) {
    507   *param;
    508 }
    509 
    510 void testFunctionParam1(ConsumableClass<int> &param) {
    511   *param; // expected-warning {{invalid invocation of method 'operator*' on object 'param' while it is in the 'unknown' state}}
    512 }
    513 
    514 void testReturnStates() {
    515   ConsumableClass<int> var;
    516 
    517   var = returnsUnconsumed();
    518   *var;
    519 
    520   var = returnsConsumed();
    521   *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}}
    522 }
    523 
    524 void testCallableWhen() {
    525   ConsumableClass<int> var(42);
    526 
    527   *var;
    528 
    529   baf4(var);
    530 
    531   var.callableWhenUnknown();
    532 }
    533 
    534 void testMoveAsignmentish() {
    535   ConsumableClass<int>  var0;
    536   ConsumableClass<long> var1(42);
    537 
    538   *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
    539   *var1;
    540 
    541   var0 = static_cast<ConsumableClass<long>&&>(var1);
    542 
    543   *var0;
    544   *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
    545 
    546   var1 = ConsumableClass<long>(42);
    547   var1 = nullptr;
    548   *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
    549 }
    550 
    551 void testConditionalMerge() {
    552   ConsumableClass<int> var;
    553 
    554   if (var.isValid()) {
    555     // Empty
    556   }
    557 
    558   *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}}
    559 
    560   if (var.isValid()) {
    561     // Empty
    562   } else {
    563     // Empty
    564   }
    565 
    566   *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}}
    567 }
    568 
    569 void testSetTypestate() {
    570   ConsumableClass<int> var(42);
    571 
    572   *var;
    573 
    574   var.consume();
    575 
    576   *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}}
    577 
    578   var.unconsume();
    579 
    580   *var;
    581 }
    582 
    583 void testConsumes0() {
    584   ConsumableClass<int> var(nullptr);
    585 
    586   *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}}
    587 }
    588 
    589 void testConsumes1() {
    590   ConsumableClass<int> var(42);
    591 
    592   var.unconsumedCall();
    593   var(6);
    594 
    595   var.unconsumedCall(); // expected-warning {{invalid invocation of method 'unconsumedCall' on object 'var' while it is in the 'consumed' state}}
    596 }
    597 
    598 void testUnreachableBlock() {
    599   ConsumableClass<int> var(42);
    600 
    601   if (var) {
    602     *var;
    603   } else {
    604     *var;
    605   }
    606 
    607   *var;
    608 }
    609 
    610 
    611 void testForLoop1() {
    612   ConsumableClass<int> var0, var1(42);
    613 
    614   for (int i = 0; i < 10; ++i) { // expected-warning {{state of variable 'var1' must match at the entry and exit of loop}}
    615     *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
    616 
    617     *var1;
    618     var1.consume();
    619     *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
    620   }
    621 
    622   *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
    623 }
    624 
    625 void testWhileLoop1() {
    626   int i = 10;
    627 
    628   ConsumableClass<int> var0, var1(42);
    629 
    630   while (i-- > 0) { // expected-warning {{state of variable 'var1' must match at the entry and exit of loop}}
    631     *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
    632 
    633     *var1;
    634     var1.consume();
    635     *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
    636   }
    637 
    638   *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
    639 }
    640 
    641 typedef const int*& IntegerPointerReference;
    642 void testIsRValueRefishAndCanonicalType(IntegerPointerReference a) {}
    643 
    644 namespace ContinueICETest {
    645 
    646 bool cond1();
    647 bool cond2();
    648 
    649 static void foo1() {
    650   while (cond1()) {
    651     if (cond2())
    652       continue;
    653   }
    654 }
    655 
    656 static void foo2() {
    657   while (true) {
    658     if (false)
    659       continue;
    660   }
    661 }
    662 
    663 class runtime_error
    664 {
    665 public:
    666   virtual ~runtime_error();
    667 };
    668 
    669 void read(bool sf) {
    670     while (sf) {
    671         if(sf) throw runtime_error();
    672     }
    673 }
    674 
    675 } // end namespace ContinueICETest
    676 
    677 
    678 namespace StatusUseCaseTests {
    679 
    680 class CONSUMABLE(unconsumed)
    681       __attribute__((consumable_auto_cast_state))
    682       __attribute__((consumable_set_state_on_read))
    683     Status {
    684   int code;
    685 
    686 public:
    687   static Status OK;
    688 
    689   Status() RETURN_TYPESTATE(consumed);
    690   Status(int c) RETURN_TYPESTATE(unconsumed);
    691 
    692   Status(const Status &other);
    693   Status(Status &&other);
    694 
    695   Status& operator=(const Status &other) CALLABLE_WHEN("unknown", "consumed");
    696   Status& operator=(Status &&other) CALLABLE_WHEN("unknown", "consumed");
    697 
    698   bool operator==(const Status &other) const SET_TYPESTATE(consumed);
    699 
    700   bool check()  const SET_TYPESTATE(consumed);
    701   void ignore() const SET_TYPESTATE(consumed);
    702   // Status& markAsChecked() { return *this; }
    703 
    704   void clear() CALLABLE_WHEN("unknown", "consumed") SET_TYPESTATE(consumed);
    705 
    706   ~Status() CALLABLE_WHEN("unknown", "consumed");
    707 
    708   operator bool() const; // Will not consume the object.
    709 };
    710 
    711 
    712 bool   cond();
    713 Status doSomething();
    714 void   handleStatus(const Status& s RETURN_TYPESTATE(consumed));
    715 void   handleStatusRef(Status& s);
    716 void   handleStatusPtr(Status* s);
    717 void   handleStatusUnmarked(const Status& s);
    718 
    719 void   log(const char* msg);
    720 void   fail() __attribute__((noreturn));
    721 void   checkStat(const Status& s);
    722 
    723 
    724 void testSimpleTemporaries0() {
    725   doSomething(); // expected-warning {{invalid invocation of method '~Status' on a temporary object while it is in the 'unconsumed' state}}
    726 }
    727 
    728 void testSimpleTemporaries1() {
    729   doSomething().ignore();
    730 }
    731 
    732 void testSimpleTemporaries2() {
    733   handleStatus(doSomething());
    734 }
    735 
    736 void testSimpleTemporaries3() {
    737   Status s = doSomething();
    738 }  // expected-warning {{invalid invocation of method '~Status' on object 's' while it is in the 'unconsumed' state}}
    739 
    740 void testTemporariesWithControlFlow(bool a) {
    741   bool b = false || doSomething(); // expected-warning {{invalid invocation of method '~Status' on a temporary object while it is in the 'unconsumed' state}}
    742 }
    743 
    744 Status testSimpleTemporariesReturn0() {
    745   return doSomething();
    746 }
    747 
    748 Status testSimpleTemporariesReturn1() {
    749   Status s = doSomething();
    750   return s;
    751 }
    752 
    753 void testSimpleTemporaries4() {
    754   Status s = doSomething();
    755   s.check();
    756 }
    757 
    758 void testSimpleTemporaries5() {
    759   Status s = doSomething();
    760   s.clear(); // expected-warning {{invalid invocation of method 'clear' on object 's' while it is in the 'unconsumed' state}}
    761 }
    762 
    763 void testSimpleTemporaries6() {
    764   Status s1 = doSomething();
    765   handleStatus(s1);
    766 
    767   Status s2 = doSomething();
    768   handleStatusRef(s2);
    769 
    770   Status s3 = doSomething();
    771   handleStatusPtr(&s3);
    772 
    773   Status s4 = doSomething();
    774   handleStatusUnmarked(s4);
    775 }
    776 
    777 void testSimpleTemporaries7() {
    778   Status s;
    779   s = doSomething();
    780 }  // expected-warning {{invalid invocation of method '~Status' on object 's' while it is in the 'unconsumed' state}}
    781 
    782 void testTemporariesWithConditionals0() {
    783   int a;
    784 
    785   Status s = doSomething();
    786   if (cond()) a = 0;
    787   else        a = 1;
    788 } // expected-warning {{invalid invocation of method '~Status' on object 's' while it is in the 'unconsumed' state}}
    789 
    790 void testTemporariesWithConditionals1() {
    791   int a;
    792 
    793   Status s = doSomething();
    794   if (cond()) a = 0;
    795   else        a = 1;
    796   s.ignore();
    797 }
    798 
    799 void testTemporariesWithConditionals2() {
    800   int a;
    801 
    802   Status s = doSomething();
    803   s.ignore();
    804   if (cond()) a = 0;
    805   else        a = 1;
    806 }
    807 
    808 void testTemporariesWithConditionals3() {
    809   Status s = doSomething();
    810   if (cond()) {
    811     s.check();
    812   }
    813 }
    814 
    815 void testTemporariesAndConstructors0() {
    816   Status s(doSomething());    // Test the copy constructor.
    817   s.check();
    818 }
    819 
    820 void testTemporariesAndConstructors1F() {
    821   Status s1 = doSomething();  // Test the copy constructor.
    822   Status s2 = s1;
    823 } // expected-warning {{invalid invocation of method '~Status' on object 's2' while it is in the 'unconsumed' state}}
    824 
    825 void testTemporariesAndConstructors1S() {
    826   Status s1 = doSomething();  // Test the copy constructor.
    827   Status s2(s1);
    828   s2.check();
    829 }
    830 
    831 void testTemporariesAndConstructors2F() {
    832   // Test the move constructor.
    833   Status s1 = doSomething();
    834   Status s2 = static_cast<Status&&>(s1);
    835 } // expected-warning {{invalid invocation of method '~Status' on object 's2' while it is in the 'unconsumed' state}}
    836 
    837 void testTemporariesAndConstructors2S() {
    838   // Test the move constructor.
    839   Status s1 = doSomething();
    840   Status s2 = static_cast<Status&&>(s1);
    841   s2.check();
    842 }
    843 
    844 void testTemporariesAndOperators0F() {
    845   // Test the assignment operator.
    846   Status s1 = doSomething();
    847   Status s2;
    848   s2 = s1;
    849 } // expected-warning {{invalid invocation of method '~Status' on object 's2' while it is in the 'unconsumed' state}}
    850 
    851 void testTemporariesAndOperators0S() {
    852   // Test the assignment operator.
    853   Status s1 = doSomething();
    854   Status s2;
    855   s2 = s1;
    856   s2.check();
    857 }
    858 
    859 void testTemporariesAndOperators1F() {
    860   // Test the move assignment operator.
    861   Status s1 = doSomething();
    862   Status s2;
    863   s2 = static_cast<Status&&>(s1);
    864 } // expected-warning {{invalid invocation of method '~Status' on object 's2' while it is in the 'unconsumed' state}}
    865 
    866 void testTemporariesAndOperators1S() {
    867   // Test the move assignment operator.
    868   Status s1 = doSomething();
    869   Status s2;
    870   s2 = static_cast<Status&&>(s1);
    871   s2.check();
    872 }
    873 
    874 void testTemporariesAndOperators2() {
    875   Status s1 = doSomething();
    876   Status s2 = doSomething();
    877   s1 = s2; // expected-warning {{invalid invocation of method 'operator=' on object 's1' while it is in the 'unconsumed' state}}
    878   s1.check();
    879   s2.check();
    880 }
    881 
    882 Status testReturnAutocast() {
    883   Status s = doSomething();
    884   s.check();  // consume s
    885   return s;   // should autocast back to unconsumed
    886 }
    887 
    888 
    889 namespace TestParens {
    890 
    891 void test3() {
    892   checkStat((doSomething()));
    893 }
    894 
    895 void test4() {
    896   Status s = (doSomething());
    897   s.check();
    898 }
    899 
    900 void test5() {
    901   (doSomething()).check();
    902 }
    903 
    904 void test6() {
    905   if ((doSomething()) == Status::OK)
    906     return;
    907 }
    908 
    909 } // end namespace TestParens
    910 
    911 } // end namespace InitializerAssertionFailTest
    912 
    913 
    914 namespace std {
    915   void move();
    916   template<class T>
    917   void move(T&&);
    918 
    919   namespace __1 {
    920     void move();
    921     template<class T>
    922     void move(T&&);
    923   }
    924 }
    925 
    926 namespace PR18260 {
    927   class X {
    928     public:
    929       void move();
    930   } x;
    931 
    932   void test() {
    933     x.move();
    934     std::move();
    935     std::move(x);
    936     std::__1::move();
    937     std::__1::move(x);
    938   }
    939 } // end namespace PR18260
    940 
    941