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 // Tests if state information is correctly discarded for certain shapes of CFGs.
    642 void testSwitchGOTO(void) {
    643 	int a;
    644 
    645 	LABEL0:
    646 	switch (a)
    647 	case 0:
    648 		goto LABEL0;
    649 
    650 	goto LABEL0;
    651 }
    652 
    653 typedef const int*& IntegerPointerReference;
    654 void testIsRValueRefishAndCanonicalType(IntegerPointerReference a) {}
    655 
    656 namespace ContinueICETest {
    657 
    658 bool cond1();
    659 bool cond2();
    660 
    661 static void foo1() {
    662   while (cond1()) {
    663     if (cond2())
    664       continue;
    665   }
    666 }
    667 
    668 static void foo2() {
    669   while (true) {
    670     if (false)
    671       continue;
    672   }
    673 }
    674 
    675 class runtime_error
    676 {
    677 public:
    678   virtual ~runtime_error();
    679 };
    680 
    681 void read(bool sf) {
    682     while (sf) {
    683         if(sf) throw runtime_error();
    684     }
    685 }
    686 
    687 } // end namespace ContinueICETest
    688 
    689 
    690 namespace StatusUseCaseTests {
    691 
    692 class CONSUMABLE(unconsumed)
    693       __attribute__((consumable_auto_cast_state))
    694       __attribute__((consumable_set_state_on_read))
    695     Status {
    696   int code;
    697 
    698 public:
    699   static Status OK;
    700 
    701   Status() RETURN_TYPESTATE(consumed);
    702   Status(int c) RETURN_TYPESTATE(unconsumed);
    703 
    704   Status(const Status &other);
    705   Status(Status &&other);
    706 
    707   Status& operator=(const Status &other) CALLABLE_WHEN("unknown", "consumed");
    708   Status& operator=(Status &&other) CALLABLE_WHEN("unknown", "consumed");
    709 
    710   bool operator==(const Status &other) const SET_TYPESTATE(consumed);
    711 
    712   bool check()  const SET_TYPESTATE(consumed);
    713   void ignore() const SET_TYPESTATE(consumed);
    714   // Status& markAsChecked() { return *this; }
    715 
    716   void clear() CALLABLE_WHEN("unknown", "consumed") SET_TYPESTATE(consumed);
    717 
    718   ~Status() CALLABLE_WHEN("unknown", "consumed");
    719 
    720   operator bool() const; // Will not consume the object.
    721 };
    722 
    723 
    724 bool   cond();
    725 Status doSomething();
    726 void   handleStatus(const Status& s RETURN_TYPESTATE(consumed));
    727 void   handleStatusRef(Status& s);
    728 void   handleStatusPtr(Status* s);
    729 void   handleStatusUnmarked(const Status& s);
    730 
    731 void   log(const char* msg);
    732 void   fail() __attribute__((noreturn));
    733 void   checkStat(const Status& s);
    734 
    735 
    736 void testSimpleTemporaries0() {
    737   doSomething(); // expected-warning {{invalid invocation of method '~Status' on a temporary object while it is in the 'unconsumed' state}}
    738 }
    739 
    740 void testSimpleTemporaries1() {
    741   doSomething().ignore();
    742 }
    743 
    744 void testSimpleTemporaries2() {
    745   handleStatus(doSomething());
    746 }
    747 
    748 void testSimpleTemporaries3() {
    749   Status s = doSomething();
    750 }  // expected-warning {{invalid invocation of method '~Status' on object 's' while it is in the 'unconsumed' state}}
    751 
    752 void testTemporariesWithControlFlow(bool a) {
    753   bool b = false || doSomething(); // expected-warning {{invalid invocation of method '~Status' on a temporary object while it is in the 'unconsumed' state}}
    754 }
    755 
    756 Status testSimpleTemporariesReturn0() {
    757   return doSomething();
    758 }
    759 
    760 Status testSimpleTemporariesReturn1() {
    761   Status s = doSomething();
    762   return s;
    763 }
    764 
    765 void testSimpleTemporaries4() {
    766   Status s = doSomething();
    767   s.check();
    768 }
    769 
    770 void testSimpleTemporaries5() {
    771   Status s = doSomething();
    772   s.clear(); // expected-warning {{invalid invocation of method 'clear' on object 's' while it is in the 'unconsumed' state}}
    773 }
    774 
    775 void testSimpleTemporaries6() {
    776   Status s1 = doSomething();
    777   handleStatus(s1);
    778 
    779   Status s2 = doSomething();
    780   handleStatusRef(s2);
    781 
    782   Status s3 = doSomething();
    783   handleStatusPtr(&s3);
    784 
    785   Status s4 = doSomething();
    786   handleStatusUnmarked(s4);
    787 }
    788 
    789 void testSimpleTemporaries7() {
    790   Status s;
    791   s = doSomething();
    792 }  // expected-warning {{invalid invocation of method '~Status' on object 's' while it is in the 'unconsumed' state}}
    793 
    794 void testTemporariesWithConditionals0() {
    795   int a;
    796 
    797   Status s = doSomething();
    798   if (cond()) a = 0;
    799   else        a = 1;
    800 } // expected-warning {{invalid invocation of method '~Status' on object 's' while it is in the 'unconsumed' state}}
    801 
    802 void testTemporariesWithConditionals1() {
    803   int a;
    804 
    805   Status s = doSomething();
    806   if (cond()) a = 0;
    807   else        a = 1;
    808   s.ignore();
    809 }
    810 
    811 void testTemporariesWithConditionals2() {
    812   int a;
    813 
    814   Status s = doSomething();
    815   s.ignore();
    816   if (cond()) a = 0;
    817   else        a = 1;
    818 }
    819 
    820 void testTemporariesWithConditionals3() {
    821   Status s = doSomething();
    822   if (cond()) {
    823     s.check();
    824   }
    825 }
    826 
    827 void testTemporariesAndConstructors0() {
    828   Status s(doSomething());    // Test the copy constructor.
    829   s.check();
    830 }
    831 
    832 void testTemporariesAndConstructors1F() {
    833   Status s1 = doSomething();  // Test the copy constructor.
    834   Status s2 = s1;
    835 } // expected-warning {{invalid invocation of method '~Status' on object 's2' while it is in the 'unconsumed' state}}
    836 
    837 void testTemporariesAndConstructors1S() {
    838   Status s1 = doSomething();  // Test the copy constructor.
    839   Status s2(s1);
    840   s2.check();
    841 }
    842 
    843 void testTemporariesAndConstructors2F() {
    844   // Test the move constructor.
    845   Status s1 = doSomething();
    846   Status s2 = static_cast<Status&&>(s1);
    847 } // expected-warning {{invalid invocation of method '~Status' on object 's2' while it is in the 'unconsumed' state}}
    848 
    849 void testTemporariesAndConstructors2S() {
    850   // Test the move constructor.
    851   Status s1 = doSomething();
    852   Status s2 = static_cast<Status&&>(s1);
    853   s2.check();
    854 }
    855 
    856 void testTemporariesAndOperators0F() {
    857   // Test the assignment operator.
    858   Status s1 = doSomething();
    859   Status s2;
    860   s2 = s1;
    861 } // expected-warning {{invalid invocation of method '~Status' on object 's2' while it is in the 'unconsumed' state}}
    862 
    863 void testTemporariesAndOperators0S() {
    864   // Test the assignment operator.
    865   Status s1 = doSomething();
    866   Status s2;
    867   s2 = s1;
    868   s2.check();
    869 }
    870 
    871 void testTemporariesAndOperators1F() {
    872   // Test the move assignment operator.
    873   Status s1 = doSomething();
    874   Status s2;
    875   s2 = static_cast<Status&&>(s1);
    876 } // expected-warning {{invalid invocation of method '~Status' on object 's2' while it is in the 'unconsumed' state}}
    877 
    878 void testTemporariesAndOperators1S() {
    879   // Test the move assignment operator.
    880   Status s1 = doSomething();
    881   Status s2;
    882   s2 = static_cast<Status&&>(s1);
    883   s2.check();
    884 }
    885 
    886 void testTemporariesAndOperators2() {
    887   Status s1 = doSomething();
    888   Status s2 = doSomething();
    889   s1 = s2; // expected-warning {{invalid invocation of method 'operator=' on object 's1' while it is in the 'unconsumed' state}}
    890   s1.check();
    891   s2.check();
    892 }
    893 
    894 Status testReturnAutocast() {
    895   Status s = doSomething();
    896   s.check();  // consume s
    897   return s;   // should autocast back to unconsumed
    898 }
    899 
    900 
    901 namespace TestParens {
    902 
    903 void test3() {
    904   checkStat((doSomething()));
    905 }
    906 
    907 void test4() {
    908   Status s = (doSomething());
    909   s.check();
    910 }
    911 
    912 void test5() {
    913   (doSomething()).check();
    914 }
    915 
    916 void test6() {
    917   if ((doSomething()) == Status::OK)
    918     return;
    919 }
    920 
    921 } // end namespace TestParens
    922 
    923 } // end namespace InitializerAssertionFailTest
    924 
    925 
    926 namespace std {
    927   void move();
    928   template<class T>
    929   void move(T&&);
    930 
    931   namespace __1 {
    932     void move();
    933     template<class T>
    934     void move(T&&);
    935   }
    936 }
    937 
    938 namespace PR18260 {
    939   class X {
    940     public:
    941       void move();
    942   } x;
    943 
    944   void test() {
    945     x.move();
    946     std::move();
    947     std::move(x);
    948     std::__1::move();
    949     std::__1::move(x);
    950   }
    951 } // end namespace PR18260
    952 
    953