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() RETURN_TYPESTATE(unconsumed); 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 86 var0 = ConsumableClass<int>(); 87 88 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} 89 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}} 90 91 if (var0.isValid()) { 92 *var0; 93 *var1; 94 95 } else { 96 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} 97 } 98 } 99 100 void testDestruction() { 101 DestructorTester D0(42), D1(42); 102 103 *D0; 104 *D1; 105 106 DestructorTester D2; 107 *D2; 108 109 D0.~DestructorTester(); // expected-warning {{invalid invocation of method '~DestructorTester' on object 'D0' while it is in the 'unconsumed' state}} 110 111 return; // expected-warning {{invalid invocation of method '~DestructorTester' on object 'D0' while it is in the 'unconsumed' state}} \ 112 expected-warning {{invalid invocation of method '~DestructorTester' on object 'D1' while it is in the 'unconsumed' state}} \ 113 expected-warning {{invalid invocation of method '~DestructorTester' on object 'D2' while it is in the 'unconsumed' state}} 114 } 115 116 void testTempValue() { 117 *ConsumableClass<int>(); // expected-warning {{invalid invocation of method 'operator*' on a temporary object while it is in the 'consumed' state}} 118 } 119 120 void testSimpleRValueRefs() { 121 ConsumableClass<int> var0; 122 ConsumableClass<int> var1(42); 123 124 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} 125 *var1; 126 127 var0 = static_cast<ConsumableClass<int>&&>(var1); 128 129 *var0; 130 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}} 131 } 132 133 void testIfStmt() { 134 ConsumableClass<int> var; 135 136 if (var.isValid()) { 137 *var; 138 } else { 139 *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}} 140 } 141 142 if (!var.isValid()) { 143 *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}} 144 } else { 145 *var; 146 } 147 148 if (var) { 149 // Empty 150 } else { 151 *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}} 152 } 153 154 if (var != nullptr) { 155 // Empty 156 } else { 157 *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}} 158 } 159 160 if (var == nullptr) { 161 *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}} 162 } else { 163 // Empty 164 } 165 } 166 167 void testComplexConditionals0() { 168 ConsumableClass<int> var0, var1, var2; 169 170 if (var0 && var1) { 171 *var0; 172 *var1; 173 174 } else { 175 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} 176 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}} 177 } 178 179 if (var0 || var1) { 180 *var0; 181 *var1; 182 183 } else { 184 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} 185 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}} 186 } 187 188 if (var0 && !var1) { 189 *var0; 190 *var1; 191 192 } else { 193 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} 194 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}} 195 } 196 197 if (var0 || !var1) { 198 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} 199 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}} 200 201 } else { 202 *var0; 203 *var1; 204 } 205 206 if (!var0 && !var1) { 207 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} 208 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}} 209 210 } else { 211 *var0; 212 *var1; 213 } 214 215 if (!var0 || !var1) { 216 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} 217 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}} 218 219 } else { 220 *var0; 221 *var1; 222 } 223 224 if (!(var0 && var1)) { 225 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} 226 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}} 227 228 } else { 229 *var0; 230 *var1; 231 } 232 233 if (!(var0 || var1)) { 234 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} 235 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}} 236 237 } else { 238 *var0; 239 *var1; 240 } 241 242 if (var0 && var1 && var2) { 243 *var0; 244 *var1; 245 *var2; 246 247 } else { 248 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} 249 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}} 250 *var2; // expected-warning {{invalid invocation of method 'operator*' on object 'var2' while it is in the 'consumed' state}} 251 } 252 253 #if 0 254 // FIXME: Get this test to pass. 255 if (var0 || var1 || var2) { 256 *var0; 257 *var1; 258 *var2; 259 260 } else { 261 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} 262 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}} 263 *var2; // expected-warning {{invalid invocation of method 'operator*' on object 'var2' while it is in the 'consumed' state}} 264 } 265 #endif 266 } 267 268 void testComplexConditionals1() { 269 ConsumableClass<int> var0, var1, var2; 270 271 // Coerce all variables into the unknown state. 272 baf4(var0); 273 baf4(var1); 274 baf4(var2); 275 276 if (var0 && var1) { 277 *var0; 278 *var1; 279 280 } else { 281 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}} 282 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}} 283 } 284 285 if (var0 || var1) { 286 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}} 287 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}} 288 289 } else { 290 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} 291 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}} 292 } 293 294 if (var0 && !var1) { 295 *var0; 296 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}} 297 298 } else { 299 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}} 300 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}} 301 } 302 303 if (var0 || !var1) { 304 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}} 305 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}} 306 307 } else { 308 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} 309 *var1; 310 } 311 312 if (!var0 && !var1) { 313 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} 314 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}} 315 316 } else { 317 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}} 318 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}} 319 } 320 321 if (!(var0 || var1)) { 322 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} 323 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}} 324 325 } else { 326 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}} 327 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}} 328 } 329 330 if (!var0 || !var1) { 331 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}} 332 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}} 333 334 } else { 335 *var0; 336 *var1; 337 } 338 339 if (!(var0 && var1)) { 340 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}} 341 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}} 342 343 } else { 344 *var0; 345 *var1; 346 } 347 348 if (var0 && var1 && var2) { 349 *var0; 350 *var1; 351 *var2; 352 353 } else { 354 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}} 355 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}} 356 *var2; // expected-warning {{invalid invocation of method 'operator*' on object 'var2' while it is in the 'unknown' state}} 357 } 358 359 #if 0 360 // FIXME: Get this test to pass. 361 if (var0 || var1 || var2) { 362 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}} 363 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}} 364 *var2; // expected-warning {{invalid invocation of method 'operator*' on object 'var2' while it is in the 'unknown' state}} 365 366 } else { 367 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} 368 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}} 369 *var2; // expected-warning {{invalid invocation of method 'operator*' on object 'var2' while it is in the 'consumed' state}} 370 } 371 #endif 372 } 373 374 void testStateChangeInBranch() { 375 ConsumableClass<int> var; 376 377 // Make var enter the 'unknown' state. 378 baf4(var); 379 380 if (!var) { 381 var = ConsumableClass<int>(42); 382 } 383 384 *var; 385 } 386 387 void testFunctionParam(ConsumableClass<int> param) { 388 389 if (param.isValid()) { 390 *param; 391 } else { 392 *param; 393 } 394 395 param = nullptr; 396 *param; // expected-warning {{invocation of method 'operator*' on object 'param' while it is in the 'consumed' state}} 397 } 398 399 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'}} 400 401 if (cond) { 402 Param.consume(); 403 return; // expected-warning {{parameter 'Param' not in expected state when the function returns: expected 'unconsumed', observed 'consumed'}} 404 } 405 406 Param.consume(); 407 } 408 409 void testParamReturnTypestateCaller() { 410 ConsumableClass<int> var; 411 412 testParamReturnTypestateCallee(true, var); 413 414 *var; 415 } 416 417 void testParamTypestateCallee(ConsumableClass<int> Param0 PARAM_TYPESTATE(consumed), 418 ConsumableClass<int> &Param1 PARAM_TYPESTATE(consumed)) { 419 420 *Param0; // expected-warning {{invalid invocation of method 'operator*' on object 'Param0' while it is in the 'consumed' state}} 421 *Param1; // expected-warning {{invalid invocation of method 'operator*' on object 'Param1' while it is in the 'consumed' state}} 422 } 423 424 void testParamTypestateCaller() { 425 ConsumableClass<int> Var0, Var1(42); 426 427 testParamTypestateCallee(Var0, Var1); // expected-warning {{argument not in expected state; expected 'consumed', observed 'unconsumed'}} 428 } 429 430 void baf3(ConsumableClass<int> var) { 431 *var; 432 } 433 434 void baf4(ConsumableClass<int> &var) { 435 *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'unknown' state}} 436 } 437 438 void baf6(ConsumableClass<int> &&var) { 439 *var; 440 } 441 442 void testCallingConventions() { 443 ConsumableClass<int> var(42); 444 445 baf0(var); 446 *var; 447 448 baf1(var); 449 *var; 450 451 baf2(&var); 452 *var; 453 454 baf4(var); 455 *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'unknown' state}} 456 457 var = ConsumableClass<int>(42); 458 baf5(&var); 459 *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'unknown' state}} 460 461 var = ConsumableClass<int>(42); 462 baf6(static_cast<ConsumableClass<int>&&>(var)); 463 *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}} 464 } 465 466 void testConstAndNonConstMemberFunctions() { 467 ConsumableClass<int> var(42); 468 469 var.constCall(); 470 *var; 471 472 var.nonconstCall(); 473 *var; 474 } 475 476 void testFunctionParam0(ConsumableClass<int> param) { 477 *param; 478 } 479 480 void testFunctionParam1(ConsumableClass<int> ¶m) { 481 *param; // expected-warning {{invalid invocation of method 'operator*' on object 'param' while it is in the 'unknown' state}} 482 } 483 484 void testReturnStates() { 485 ConsumableClass<int> var; 486 487 var = returnsUnconsumed(); 488 *var; 489 490 var = returnsConsumed(); 491 *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}} 492 } 493 494 void testCallableWhen() { 495 ConsumableClass<int> var(42); 496 497 *var; 498 499 baf4(var); 500 501 var.callableWhenUnknown(); 502 } 503 504 void testMoveAsignmentish() { 505 ConsumableClass<int> var0; 506 ConsumableClass<long> var1(42); 507 508 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} 509 *var1; 510 511 var0 = static_cast<ConsumableClass<long>&&>(var1); 512 513 *var0; 514 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}} 515 516 var1 = ConsumableClass<long>(42); 517 var1 = nullptr; 518 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}} 519 } 520 521 void testConditionalMerge() { 522 ConsumableClass<int> var; 523 524 if (var.isValid()) { 525 // Empty 526 } 527 528 *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}} 529 530 if (var.isValid()) { 531 // Empty 532 } else { 533 // Empty 534 } 535 536 *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}} 537 } 538 539 void testSetTypestate() { 540 ConsumableClass<int> var(42); 541 542 *var; 543 544 var.consume(); 545 546 *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}} 547 548 var.unconsume(); 549 550 *var; 551 } 552 553 void testConsumes0() { 554 ConsumableClass<int> var(nullptr); 555 556 *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}} 557 } 558 559 void testConsumes1() { 560 ConsumableClass<int> var(42); 561 562 var.unconsumedCall(); 563 var(6); 564 565 var.unconsumedCall(); // expected-warning {{invalid invocation of method 'unconsumedCall' on object 'var' while it is in the 'consumed' state}} 566 } 567 568 void testUnreachableBlock() { 569 ConsumableClass<int> var(42); 570 571 if (var) { 572 *var; 573 } else { 574 *var; 575 } 576 577 *var; 578 } 579 580 581 void testForLoop1() { 582 ConsumableClass<int> var0, var1(42); 583 584 for (int i = 0; i < 10; ++i) { // expected-warning {{state of variable 'var1' must match at the entry and exit of loop}} 585 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} 586 587 *var1; 588 var1.consume(); 589 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}} 590 } 591 592 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} 593 } 594 595 void testWhileLoop1() { 596 int i = 10; 597 598 ConsumableClass<int> var0, var1(42); 599 600 while (i-- > 0) { // expected-warning {{state of variable 'var1' must match at the entry and exit of loop}} 601 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} 602 603 *var1; 604 var1.consume(); 605 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}} 606 } 607 608 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} 609 } 610 611 typedef const int*& IntegerPointerReference; 612 void testIsRValueRefishAndCanonicalType(IntegerPointerReference a) {} 613 614 namespace ContinueICETest { 615 616 bool cond1(); 617 bool cond2(); 618 619 static void foo1() { 620 while (cond1()) { 621 if (cond2()) 622 continue; 623 } 624 } 625 626 static void foo2() { 627 while (true) { 628 if (false) 629 continue; 630 } 631 } 632 633 class runtime_error 634 { 635 public: 636 virtual ~runtime_error(); 637 }; 638 639 void read(bool sf) { 640 while (sf) { 641 if(sf) throw runtime_error(); 642 } 643 } 644 645 } // end namespace ContinueICETest 646 647 648 namespace InitializerAssertionFailTest { 649 650 class CONSUMABLE(unconsumed) Status { 651 int code; 652 653 public: 654 Status() RETURN_TYPESTATE(consumed); 655 Status(int c) RETURN_TYPESTATE(unconsumed); 656 657 Status(const Status &other); 658 Status(Status &&other); 659 660 Status& operator=(const Status &other) CALLABLE_WHEN("unknown", "consumed"); 661 Status& operator=(Status &&other) CALLABLE_WHEN("unknown", "consumed"); 662 663 bool check() const SET_TYPESTATE(consumed); 664 void ignore() const SET_TYPESTATE(consumed); 665 // Status& markAsChecked() { return *this; } 666 667 void clear() CALLABLE_WHEN("unknown", "consumed") SET_TYPESTATE(consumed); 668 669 ~Status() CALLABLE_WHEN("unknown", "consumed"); 670 }; 671 672 673 bool cond(); 674 Status doSomething(); 675 void handleStatus(const Status& s RETURN_TYPESTATE(consumed)); 676 void handleStatusPtr(const Status* s); 677 678 void testSimpleTemporaries0() { 679 doSomething(); // expected-warning {{invalid invocation of method '~Status' on a temporary object while it is in the 'unconsumed' state}} 680 } 681 682 void testSimpleTemporaries1() { 683 doSomething().ignore(); 684 } 685 686 void testSimpleTemporaries2() { 687 handleStatus(doSomething()); 688 } 689 690 void testSimpleTemporaries3() { 691 Status s = doSomething(); 692 } // expected-warning {{invalid invocation of method '~Status' on object 's' while it is in the 'unconsumed' state}} 693 694 void testSimpleTemporaries4() { 695 Status s = doSomething(); 696 s.check(); 697 } 698 699 void testSimpleTemporaries5() { 700 Status s = doSomething(); 701 s.clear(); // expected-warning {{invalid invocation of method 'clear' on object 's' while it is in the 'unconsumed' state}} 702 } 703 704 void testSimpleTemporaries6() { 705 Status s = doSomething(); 706 handleStatus(s); 707 } 708 709 void testSimpleTemporaries7() { 710 Status s; 711 s = doSomething(); 712 } // expected-warning {{invalid invocation of method '~Status' on object 's' while it is in the 'unconsumed' state}} 713 714 void testTemporariesWithConditionals0() { 715 int a; 716 717 Status s = doSomething(); 718 if (cond()) a = 0; 719 else a = 1; 720 } // expected-warning {{invalid invocation of method '~Status' on object 's' while it is in the 'unconsumed' state}} 721 722 void testTemporariesWithConditionals1() { 723 int a; 724 725 Status s = doSomething(); 726 if (cond()) a = 0; 727 else a = 1; 728 s.ignore(); 729 } 730 731 void testTemporariesWithConditionals2() { 732 int a; 733 734 Status s = doSomething(); 735 s.ignore(); 736 if (cond()) a = 0; 737 else a = 1; 738 } 739 740 void testTemporariesWithConditionals3() { 741 Status s = doSomething(); 742 if (cond()) { 743 s.check(); 744 } 745 } 746 747 void testTemporariesAndConstructors0() { 748 Status s(doSomething()); 749 s.check(); 750 } 751 752 void testTemporariesAndConstructors1() { 753 // Test the copy constructor. 754 755 Status s1 = doSomething(); 756 Status s2(s1); 757 s2.check(); 758 } // expected-warning {{invalid invocation of method '~Status' on object 's1' while it is in the 'unconsumed' state}} 759 760 void testTemporariesAndConstructors2() { 761 // Test the move constructor. 762 763 Status s1 = doSomething(); 764 Status s2(static_cast<Status&&>(s1)); 765 s2.check(); 766 } 767 768 void testTemporariesAndOperators0() { 769 // Test the assignment operator. 770 771 Status s1 = doSomething(); 772 Status s2; 773 s2 = s1; 774 s2.check(); 775 } // expected-warning {{invalid invocation of method '~Status' on object 's1' while it is in the 'unconsumed' state}} 776 777 void testTemporariesAndOperators1() { 778 // Test the move assignment operator. 779 780 Status s1 = doSomething(); 781 Status s2; 782 s2 = static_cast<Status&&>(s1); 783 s2.check(); 784 } 785 786 void testTemporariesAndOperators2() { 787 Status s1 = doSomething(); 788 Status s2 = doSomething(); 789 s1 = s2; // expected-warning {{invalid invocation of method 'operator=' on object 's1' while it is in the 'unconsumed' state}} 790 s1.check(); 791 s2.check(); 792 } 793 794 } // end namespace InitializerAssertionFailTest 795 796