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> ¶m) { 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