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 // 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