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 709 710 bool cond(); 711 Status doSomething(); 712 void handleStatus(const Status& s RETURN_TYPESTATE(consumed)); 713 void handleStatusRef(Status& s); 714 void handleStatusPtr(Status* s); 715 void handleStatusUnmarked(const Status& s); 716 717 void log(const char* msg); 718 void fail() __attribute__((noreturn)); 719 void checkStat(const Status& s); 720 721 722 void testSimpleTemporaries0() { 723 doSomething(); // expected-warning {{invalid invocation of method '~Status' on a temporary object while it is in the 'unconsumed' state}} 724 } 725 726 void testSimpleTemporaries1() { 727 doSomething().ignore(); 728 } 729 730 void testSimpleTemporaries2() { 731 handleStatus(doSomething()); 732 } 733 734 void testSimpleTemporaries3() { 735 Status s = doSomething(); 736 } // expected-warning {{invalid invocation of method '~Status' on object 's' while it is in the 'unconsumed' state}} 737 738 Status testSimpleTemporariesReturn0() { 739 return doSomething(); 740 } 741 742 Status testSimpleTemporariesReturn1() { 743 Status s = doSomething(); 744 return s; 745 } 746 747 void testSimpleTemporaries4() { 748 Status s = doSomething(); 749 s.check(); 750 } 751 752 void testSimpleTemporaries5() { 753 Status s = doSomething(); 754 s.clear(); // expected-warning {{invalid invocation of method 'clear' on object 's' while it is in the 'unconsumed' state}} 755 } 756 757 void testSimpleTemporaries6() { 758 Status s1 = doSomething(); 759 handleStatus(s1); 760 761 Status s2 = doSomething(); 762 handleStatusRef(s2); 763 764 Status s3 = doSomething(); 765 handleStatusPtr(&s3); 766 767 Status s4 = doSomething(); 768 handleStatusUnmarked(s4); 769 } 770 771 void testSimpleTemporaries7() { 772 Status s; 773 s = doSomething(); 774 } // expected-warning {{invalid invocation of method '~Status' on object 's' while it is in the 'unconsumed' state}} 775 776 void testTemporariesWithConditionals0() { 777 int a; 778 779 Status s = doSomething(); 780 if (cond()) a = 0; 781 else a = 1; 782 } // expected-warning {{invalid invocation of method '~Status' on object 's' while it is in the 'unconsumed' state}} 783 784 void testTemporariesWithConditionals1() { 785 int a; 786 787 Status s = doSomething(); 788 if (cond()) a = 0; 789 else a = 1; 790 s.ignore(); 791 } 792 793 void testTemporariesWithConditionals2() { 794 int a; 795 796 Status s = doSomething(); 797 s.ignore(); 798 if (cond()) a = 0; 799 else a = 1; 800 } 801 802 void testTemporariesWithConditionals3() { 803 Status s = doSomething(); 804 if (cond()) { 805 s.check(); 806 } 807 } 808 809 void testTemporariesAndConstructors0() { 810 Status s(doSomething()); // Test the copy constructor. 811 s.check(); 812 } 813 814 void testTemporariesAndConstructors1F() { 815 Status s1 = doSomething(); // Test the copy constructor. 816 Status s2 = s1; 817 } // expected-warning {{invalid invocation of method '~Status' on object 's2' while it is in the 'unconsumed' state}} 818 819 void testTemporariesAndConstructors1S() { 820 Status s1 = doSomething(); // Test the copy constructor. 821 Status s2(s1); 822 s2.check(); 823 } 824 825 void testTemporariesAndConstructors2F() { 826 // Test the move constructor. 827 Status s1 = doSomething(); 828 Status s2 = static_cast<Status&&>(s1); 829 } // expected-warning {{invalid invocation of method '~Status' on object 's2' while it is in the 'unconsumed' state}} 830 831 void testTemporariesAndConstructors2S() { 832 // Test the move constructor. 833 Status s1 = doSomething(); 834 Status s2 = static_cast<Status&&>(s1); 835 s2.check(); 836 } 837 838 void testTemporariesAndOperators0F() { 839 // Test the assignment operator. 840 Status s1 = doSomething(); 841 Status s2; 842 s2 = s1; 843 } // expected-warning {{invalid invocation of method '~Status' on object 's2' while it is in the 'unconsumed' state}} 844 845 void testTemporariesAndOperators0S() { 846 // Test the assignment operator. 847 Status s1 = doSomething(); 848 Status s2; 849 s2 = s1; 850 s2.check(); 851 } 852 853 void testTemporariesAndOperators1F() { 854 // Test the move assignment operator. 855 Status s1 = doSomething(); 856 Status s2; 857 s2 = static_cast<Status&&>(s1); 858 } // expected-warning {{invalid invocation of method '~Status' on object 's2' while it is in the 'unconsumed' state}} 859 860 void testTemporariesAndOperators1S() { 861 // Test the move assignment operator. 862 Status s1 = doSomething(); 863 Status s2; 864 s2 = static_cast<Status&&>(s1); 865 s2.check(); 866 } 867 868 void testTemporariesAndOperators2() { 869 Status s1 = doSomething(); 870 Status s2 = doSomething(); 871 s1 = s2; // expected-warning {{invalid invocation of method 'operator=' on object 's1' while it is in the 'unconsumed' state}} 872 s1.check(); 873 s2.check(); 874 } 875 876 Status testReturnAutocast() { 877 Status s = doSomething(); 878 s.check(); // consume s 879 return s; // should autocast back to unconsumed 880 } 881 882 883 namespace TestParens { 884 885 void test3() { 886 checkStat((doSomething())); 887 } 888 889 void test4() { 890 Status s = (doSomething()); 891 s.check(); 892 } 893 894 void test5() { 895 (doSomething()).check(); 896 } 897 898 void test6() { 899 if ((doSomething()) == Status::OK) 900 return; 901 } 902 903 } // end namespace TestParens 904 905 } // end namespace InitializerAssertionFailTest 906 907 908 namespace std { 909 void move(); 910 template<class T> 911 void move(T&&); 912 913 namespace __1 { 914 void move(); 915 template<class T> 916 void move(T&&); 917 } 918 } 919 920 namespace PR18260 { 921 class X { 922 public: 923 void move(); 924 } x; 925 926 void test() { 927 x.move(); 928 std::move(); 929 std::move(x); 930 std::__1::move(); 931 std::__1::move(x); 932 } 933 } // end namespace PR18260 934 935