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 12typedef decltype(nullptr) nullptr_t; 13 14template <typename T> 15class CONSUMABLE(unconsumed) ConsumableClass { 16 T var; 17 18public: 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 52class CONSUMABLE(unconsumed) DestructorTester { 53public: 54 DestructorTester(); 55 DestructorTester(int); 56 57 void operator*() CALLABLE_WHEN("unconsumed"); 58 59 ~DestructorTester() CALLABLE_WHEN("consumed"); 60}; 61 62void baf0(const ConsumableClass<int> var); 63void baf1(const ConsumableClass<int> &var); 64void baf2(const ConsumableClass<int> *var); 65 66void baf3(ConsumableClass<int> var); 67void baf4(ConsumableClass<int> &var); 68void baf5(ConsumableClass<int> *var); 69void baf6(ConsumableClass<int> &&var); 70 71ConsumableClass<int> returnsUnconsumed() { 72 return ConsumableClass<int>(); // expected-warning {{return value not in expected state; expected 'unconsumed', observed 'consumed'}} 73} 74 75ConsumableClass<int> returnsConsumed() RETURN_TYPESTATE(consumed); 76ConsumableClass<int> returnsConsumed() { 77 return ConsumableClass<int>(); 78} 79 80ConsumableClass<int> returnsUnknown() RETURN_TYPESTATE(unknown); 81 82void 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 110void 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 123void testTempValue() { 124 *ConsumableClass<int>(); // expected-warning {{invalid invocation of method 'operator*' on a temporary object while it is in the 'consumed' state}} 125} 126 127void 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 140void 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 174void 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 275void 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 381void 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 394void 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 406void 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 416void testParamReturnTypestateCaller() { 417 ConsumableClass<int> var; 418 419 testParamReturnTypestateCallee(true, var); 420 421 *var; 422} 423 424void 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 431void 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 438void consumeFunc(ConsumableClass<int> P PARAM_TYPESTATE(unconsumed)); 439struct 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 445void operator>>(ParamTest& pt, ConsumableClass<int> P PARAM_TYPESTATE(unconsumed)); 446 447 448void 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 460void baf3(ConsumableClass<int> var) { 461 *var; 462} 463 464void 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 468void baf6(ConsumableClass<int> &&var) { 469 *var; 470} 471 472void 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 496void testConstAndNonConstMemberFunctions() { 497 ConsumableClass<int> var(42); 498 499 var.constCall(); 500 *var; 501 502 var.nonconstCall(); 503 *var; 504} 505 506void testFunctionParam0(ConsumableClass<int> param) { 507 *param; 508} 509 510void 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 514void 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 524void testCallableWhen() { 525 ConsumableClass<int> var(42); 526 527 *var; 528 529 baf4(var); 530 531 var.callableWhenUnknown(); 532} 533 534void 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 551void 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 569void 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 583void 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 589void 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 598void testUnreachableBlock() { 599 ConsumableClass<int> var(42); 600 601 if (var) { 602 *var; 603 } else { 604 *var; 605 } 606 607 *var; 608} 609 610 611void 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 625void 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 641typedef const int*& IntegerPointerReference; 642void testIsRValueRefishAndCanonicalType(IntegerPointerReference a) {} 643 644namespace ContinueICETest { 645 646bool cond1(); 647bool cond2(); 648 649static void foo1() { 650 while (cond1()) { 651 if (cond2()) 652 continue; 653 } 654} 655 656static void foo2() { 657 while (true) { 658 if (false) 659 continue; 660 } 661} 662 663class runtime_error 664{ 665public: 666 virtual ~runtime_error(); 667}; 668 669void read(bool sf) { 670 while (sf) { 671 if(sf) throw runtime_error(); 672 } 673} 674 675} // end namespace ContinueICETest 676 677 678namespace StatusUseCaseTests { 679 680class CONSUMABLE(unconsumed) 681 __attribute__((consumable_auto_cast_state)) 682 __attribute__((consumable_set_state_on_read)) 683 Status { 684 int code; 685 686public: 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 712bool cond(); 713Status doSomething(); 714void handleStatus(const Status& s RETURN_TYPESTATE(consumed)); 715void handleStatusRef(Status& s); 716void handleStatusPtr(Status* s); 717void handleStatusUnmarked(const Status& s); 718 719void log(const char* msg); 720void fail() __attribute__((noreturn)); 721void checkStat(const Status& s); 722 723 724void testSimpleTemporaries0() { 725 doSomething(); // expected-warning {{invalid invocation of method '~Status' on a temporary object while it is in the 'unconsumed' state}} 726} 727 728void testSimpleTemporaries1() { 729 doSomething().ignore(); 730} 731 732void testSimpleTemporaries2() { 733 handleStatus(doSomething()); 734} 735 736void testSimpleTemporaries3() { 737 Status s = doSomething(); 738} // expected-warning {{invalid invocation of method '~Status' on object 's' while it is in the 'unconsumed' state}} 739 740void 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 744Status testSimpleTemporariesReturn0() { 745 return doSomething(); 746} 747 748Status testSimpleTemporariesReturn1() { 749 Status s = doSomething(); 750 return s; 751} 752 753void testSimpleTemporaries4() { 754 Status s = doSomething(); 755 s.check(); 756} 757 758void 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 763void 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 777void 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 782void 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 790void testTemporariesWithConditionals1() { 791 int a; 792 793 Status s = doSomething(); 794 if (cond()) a = 0; 795 else a = 1; 796 s.ignore(); 797} 798 799void testTemporariesWithConditionals2() { 800 int a; 801 802 Status s = doSomething(); 803 s.ignore(); 804 if (cond()) a = 0; 805 else a = 1; 806} 807 808void testTemporariesWithConditionals3() { 809 Status s = doSomething(); 810 if (cond()) { 811 s.check(); 812 } 813} 814 815void testTemporariesAndConstructors0() { 816 Status s(doSomething()); // Test the copy constructor. 817 s.check(); 818} 819 820void 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 825void testTemporariesAndConstructors1S() { 826 Status s1 = doSomething(); // Test the copy constructor. 827 Status s2(s1); 828 s2.check(); 829} 830 831void 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 837void testTemporariesAndConstructors2S() { 838 // Test the move constructor. 839 Status s1 = doSomething(); 840 Status s2 = static_cast<Status&&>(s1); 841 s2.check(); 842} 843 844void 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 851void testTemporariesAndOperators0S() { 852 // Test the assignment operator. 853 Status s1 = doSomething(); 854 Status s2; 855 s2 = s1; 856 s2.check(); 857} 858 859void 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 866void 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 874void 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 882Status testReturnAutocast() { 883 Status s = doSomething(); 884 s.check(); // consume s 885 return s; // should autocast back to unconsumed 886} 887 888 889namespace TestParens { 890 891void test3() { 892 checkStat((doSomething())); 893} 894 895void test4() { 896 Status s = (doSomething()); 897 s.check(); 898} 899 900void test5() { 901 (doSomething()).check(); 902} 903 904void test6() { 905 if ((doSomething()) == Status::OK) 906 return; 907} 908 909} // end namespace TestParens 910 911} // end namespace InitializerAssertionFailTest 912 913 914namespace 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 926namespace 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