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 DestructorTester(nullptr_t) RETURN_TYPESTATE(unconsumed); 57 DestructorTester(DestructorTester &&); 58 59 void operator*() CALLABLE_WHEN("unconsumed"); 60 61 ~DestructorTester() CALLABLE_WHEN("consumed"); 62 63 }; 64 65 void dtByVal(DestructorTester); 66 void dtByValMarkUnconsumed(DestructorTester RETURN_TYPESTATE(unconsumed)); 67 68 void baf0(const ConsumableClass<int> var); 69 void baf1(const ConsumableClass<int> &var); 70 void baf2(const ConsumableClass<int> *var); 71 72 void baf3(ConsumableClass<int> var); 73 void baf4(ConsumableClass<int> &var); 74 void baf5(ConsumableClass<int> *var); 75 void baf6(ConsumableClass<int> &&var); 76 77 ConsumableClass<int> returnsUnconsumed() { 78 return ConsumableClass<int>(); // expected-warning {{return value not in expected state; expected 'unconsumed', observed 'consumed'}} 79 } 80 81 ConsumableClass<int> returnsConsumed() RETURN_TYPESTATE(consumed); 82 ConsumableClass<int> returnsConsumed() { 83 return ConsumableClass<int>(); 84 } 85 86 ConsumableClass<int> returnsUnknown() RETURN_TYPESTATE(unknown); 87 88 void testInitialization() { 89 ConsumableClass<int> var0; 90 ConsumableClass<int> var1 = ConsumableClass<int>(); 91 ConsumableClass<int> var2(42); 92 ConsumableClass<int> var3(var2); // copy constructor 93 ConsumableClass<int> var4(var0); // copy consumed value 94 95 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} 96 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}} 97 *var2; 98 *var3; 99 *var4; // expected-warning {{invalid invocation of method 'operator*' on object 'var4' while it is in the 'consumed' state}} 100 101 var0 = ConsumableClass<int>(42); 102 *var0; 103 104 var0 = var1; 105 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} 106 107 if (var0.isValid()) { 108 *var0; 109 *var1; 110 111 } else { 112 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} 113 } 114 } 115 116 void testDestruction() { 117 DestructorTester D0(42), D1(42), D2; 118 119 *D0; 120 *D1; 121 *D2; // expected-warning {{invalid invocation of method 'operator*' on object 'D2' while it is in the 'consumed' state}} 122 123 D0.~DestructorTester(); // expected-warning {{invalid invocation of method '~DestructorTester' on object 'D0' while it is in the 'unconsumed' state}} 124 125 return; // expected-warning {{invalid invocation of method '~DestructorTester' on object 'D0' while it is in the 'unconsumed' state}} \ 126 expected-warning {{invalid invocation of method '~DestructorTester' on object 'D1' while it is in the 'unconsumed' state}} 127 } 128 129 void testDestructionByVal() { 130 { 131 // both the var and the temporary are consumed: 132 DestructorTester D0(nullptr); 133 dtByVal((DestructorTester &&)D0); 134 } 135 { 136 // the var is consumed but the temporary isn't: 137 DestructorTester D1(nullptr); 138 dtByValMarkUnconsumed((DestructorTester &&)D1); // expected-warning {{invalid invocation of method '~DestructorTester' on a temporary object while it is in the 'unconsumed' state}} 139 } 140 } 141 142 void testTempValue() { 143 *ConsumableClass<int>(); // expected-warning {{invalid invocation of method 'operator*' on a temporary object while it is in the 'consumed' state}} 144 } 145 146 void testSimpleRValueRefs() { 147 ConsumableClass<int> var0; 148 ConsumableClass<int> var1(42); 149 150 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} 151 *var1; 152 153 var0 = static_cast<ConsumableClass<int>&&>(var1); 154 155 *var0; 156 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}} 157 } 158 159 void testIfStmt() { 160 ConsumableClass<int> var; 161 162 if (var.isValid()) { 163 *var; 164 } else { 165 *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}} 166 } 167 168 if (!var.isValid()) { 169 *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}} 170 } else { 171 *var; 172 } 173 174 if (var) { 175 // Empty 176 } else { 177 *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}} 178 } 179 180 if (var != nullptr) { 181 // Empty 182 } else { 183 *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}} 184 } 185 186 if (var == nullptr) { 187 *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}} 188 } else { 189 // Empty 190 } 191 } 192 193 void testComplexConditionals0() { 194 ConsumableClass<int> var0, var1, var2; 195 196 if (var0 && var1) { 197 *var0; 198 *var1; 199 200 } else { 201 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} 202 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}} 203 } 204 205 if (var0 || var1) { 206 *var0; 207 *var1; 208 209 } else { 210 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} 211 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}} 212 } 213 214 if (var0 && !var1) { 215 *var0; 216 *var1; 217 218 } else { 219 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} 220 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}} 221 } 222 223 if (var0 || !var1) { 224 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} 225 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}} 226 227 } else { 228 *var0; 229 *var1; 230 } 231 232 if (!var0 && !var1) { 233 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} 234 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}} 235 236 } else { 237 *var0; 238 *var1; 239 } 240 241 if (!var0 || !var1) { 242 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} 243 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}} 244 245 } else { 246 *var0; 247 *var1; 248 } 249 250 if (!(var0 && var1)) { 251 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} 252 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}} 253 254 } else { 255 *var0; 256 *var1; 257 } 258 259 if (!(var0 || var1)) { 260 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} 261 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}} 262 263 } else { 264 *var0; 265 *var1; 266 } 267 268 if (var0 && var1 && var2) { 269 *var0; 270 *var1; 271 *var2; 272 273 } else { 274 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} 275 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}} 276 *var2; // expected-warning {{invalid invocation of method 'operator*' on object 'var2' while it is in the 'consumed' state}} 277 } 278 279 #if 0 280 // FIXME: Get this test to pass. 281 if (var0 || var1 || var2) { 282 *var0; 283 *var1; 284 *var2; 285 286 } else { 287 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} 288 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}} 289 *var2; // expected-warning {{invalid invocation of method 'operator*' on object 'var2' while it is in the 'consumed' state}} 290 } 291 #endif 292 } 293 294 void testComplexConditionals1() { 295 ConsumableClass<int> var0, var1, var2; 296 297 // Coerce all variables into the unknown state. 298 baf4(var0); 299 baf4(var1); 300 baf4(var2); 301 302 if (var0 && var1) { 303 *var0; 304 *var1; 305 306 } else { 307 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}} 308 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}} 309 } 310 311 if (var0 || var1) { 312 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}} 313 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}} 314 315 } else { 316 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} 317 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}} 318 } 319 320 if (var0 && !var1) { 321 *var0; 322 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}} 323 324 } else { 325 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}} 326 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}} 327 } 328 329 if (var0 || !var1) { 330 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}} 331 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}} 332 333 } else { 334 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} 335 *var1; 336 } 337 338 if (!var0 && !var1) { 339 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} 340 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}} 341 342 } else { 343 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}} 344 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}} 345 } 346 347 if (!(var0 || var1)) { 348 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} 349 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}} 350 351 } else { 352 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}} 353 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}} 354 } 355 356 if (!var0 || !var1) { 357 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}} 358 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}} 359 360 } else { 361 *var0; 362 *var1; 363 } 364 365 if (!(var0 && var1)) { 366 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}} 367 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}} 368 369 } else { 370 *var0; 371 *var1; 372 } 373 374 if (var0 && var1 && var2) { 375 *var0; 376 *var1; 377 *var2; 378 379 } else { 380 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}} 381 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}} 382 *var2; // expected-warning {{invalid invocation of method 'operator*' on object 'var2' while it is in the 'unknown' state}} 383 } 384 385 #if 0 386 // FIXME: Get this test to pass. 387 if (var0 || var1 || var2) { 388 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}} 389 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}} 390 *var2; // expected-warning {{invalid invocation of method 'operator*' on object 'var2' while it is in the 'unknown' state}} 391 392 } else { 393 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} 394 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}} 395 *var2; // expected-warning {{invalid invocation of method 'operator*' on object 'var2' while it is in the 'consumed' state}} 396 } 397 #endif 398 } 399 400 void testStateChangeInBranch() { 401 ConsumableClass<int> var; 402 403 // Make var enter the 'unknown' state. 404 baf4(var); 405 406 if (!var) { 407 var = ConsumableClass<int>(42); 408 } 409 410 *var; 411 } 412 413 void testFunctionParam(ConsumableClass<int> param) { 414 415 if (param.isValid()) { 416 *param; 417 } else { 418 *param; 419 } 420 421 param = nullptr; 422 *param; // expected-warning {{invocation of method 'operator*' on object 'param' while it is in the 'consumed' state}} 423 } 424 425 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'}} 426 427 if (cond) { 428 Param.consume(); 429 return; // expected-warning {{parameter 'Param' not in expected state when the function returns: expected 'unconsumed', observed 'consumed'}} 430 } 431 432 Param.consume(); 433 } 434 435 void testRvalueRefParamReturnTypestateCallee(ConsumableClass<int> &&Param RETURN_TYPESTATE(unconsumed)) { 436 Param.unconsume(); 437 } 438 439 void testParamReturnTypestateCaller() { 440 ConsumableClass<int> var; 441 442 testParamReturnTypestateCallee(true, var); 443 testRvalueRefParamReturnTypestateCallee((ConsumableClass<int> &&)var); 444 445 *var; 446 } 447 448 void testParamTypestateCallee(ConsumableClass<int> Param0 PARAM_TYPESTATE(consumed), 449 ConsumableClass<int> &Param1 PARAM_TYPESTATE(consumed)) { 450 451 *Param0; // expected-warning {{invalid invocation of method 'operator*' on object 'Param0' while it is in the 'consumed' state}} 452 *Param1; // expected-warning {{invalid invocation of method 'operator*' on object 'Param1' while it is in the 'consumed' state}} 453 } 454 455 void testParamTypestateCaller() { 456 ConsumableClass<int> Var0, Var1(42); 457 458 testParamTypestateCallee(Var0, Var1); // expected-warning {{argument not in expected state; expected 'consumed', observed 'unconsumed'}} 459 } 460 461 462 void consumeFunc(ConsumableClass<int> P PARAM_TYPESTATE(unconsumed)); 463 struct ParamTest { 464 static void consumeFuncStatic(ConsumableClass<int> P PARAM_TYPESTATE(unconsumed)); 465 void consumeFuncMeth(ConsumableClass<int> P PARAM_TYPESTATE(unconsumed)); 466 void operator<<(ConsumableClass<int> P PARAM_TYPESTATE(unconsumed)); 467 }; 468 469 void operator>>(ParamTest& pt, ConsumableClass<int> P PARAM_TYPESTATE(unconsumed)); 470 471 472 void testFunctionParams() { 473 // Make sure we handle the different kinds of functions. 474 ConsumableClass<int> P; 475 476 consumeFunc(P); // expected-warning {{argument not in expected state; expected 'unconsumed', observed 'consumed'}} 477 ParamTest::consumeFuncStatic(P); // expected-warning {{argument not in expected state; expected 'unconsumed', observed 'consumed'}} 478 ParamTest pt; 479 pt.consumeFuncMeth(P); // expected-warning {{argument not in expected state; expected 'unconsumed', observed 'consumed'}} 480 pt << P; // expected-warning {{argument not in expected state; expected 'unconsumed', observed 'consumed'}} 481 pt >> P; // expected-warning {{argument not in expected state; expected 'unconsumed', observed 'consumed'}} 482 } 483 484 void baf3(ConsumableClass<int> var) { 485 *var; 486 } 487 488 void baf4(ConsumableClass<int> &var) { 489 *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'unknown' state}} 490 } 491 492 void baf6(ConsumableClass<int> &&var) { 493 *var; 494 } 495 496 void testCallingConventions() { 497 ConsumableClass<int> var(42); 498 499 baf0(var); 500 *var; 501 502 baf1(var); 503 *var; 504 505 baf2(&var); 506 *var; 507 508 baf3(var); 509 *var; 510 511 baf4(var); 512 *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'unknown' state}} 513 514 var = ConsumableClass<int>(42); 515 baf5(&var); 516 *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'unknown' state}} 517 518 var = ConsumableClass<int>(42); 519 baf6(static_cast<ConsumableClass<int>&&>(var)); 520 *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}} 521 } 522 523 void testConstAndNonConstMemberFunctions() { 524 ConsumableClass<int> var(42); 525 526 var.constCall(); 527 *var; 528 529 var.nonconstCall(); 530 *var; 531 } 532 533 void testFunctionParam0(ConsumableClass<int> param) { 534 *param; 535 } 536 537 void testFunctionParam1(ConsumableClass<int> ¶m) { 538 *param; // expected-warning {{invalid invocation of method 'operator*' on object 'param' while it is in the 'unknown' state}} 539 } 540 541 void testReturnStates() { 542 ConsumableClass<int> var; 543 544 var = returnsUnconsumed(); 545 *var; 546 547 var = returnsConsumed(); 548 *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}} 549 } 550 551 void testCallableWhen() { 552 ConsumableClass<int> var(42); 553 554 *var; 555 556 baf4(var); 557 558 var.callableWhenUnknown(); 559 } 560 561 void testMoveAsignmentish() { 562 ConsumableClass<int> var0; 563 ConsumableClass<long> var1(42); 564 565 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} 566 *var1; 567 568 var0 = static_cast<ConsumableClass<long>&&>(var1); 569 570 *var0; 571 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}} 572 573 var1 = ConsumableClass<long>(42); 574 var1 = nullptr; 575 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}} 576 } 577 578 void testConditionalMerge() { 579 ConsumableClass<int> var; 580 581 if (var.isValid()) { 582 // Empty 583 } 584 585 *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}} 586 587 if (var.isValid()) { 588 // Empty 589 } else { 590 // Empty 591 } 592 593 *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}} 594 } 595 596 void testSetTypestate() { 597 ConsumableClass<int> var(42); 598 599 *var; 600 601 var.consume(); 602 603 *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}} 604 605 var.unconsume(); 606 607 *var; 608 } 609 610 void testConsumes0() { 611 ConsumableClass<int> var(nullptr); 612 613 *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}} 614 } 615 616 void testConsumes1() { 617 ConsumableClass<int> var(42); 618 619 var.unconsumedCall(); 620 var(6); 621 622 var.unconsumedCall(); // expected-warning {{invalid invocation of method 'unconsumedCall' on object 'var' while it is in the 'consumed' state}} 623 } 624 625 void testUnreachableBlock() { 626 ConsumableClass<int> var(42); 627 628 if (var) { 629 *var; 630 } else { 631 *var; 632 } 633 634 *var; 635 } 636 637 638 void testForLoop1() { 639 ConsumableClass<int> var0, var1(42); 640 641 for (int i = 0; i < 10; ++i) { // expected-warning {{state of variable 'var1' must match at the entry and exit of loop}} 642 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} 643 644 *var1; 645 var1.consume(); 646 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}} 647 } 648 649 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} 650 } 651 652 void testWhileLoop1() { 653 int i = 10; 654 655 ConsumableClass<int> var0, var1(42); 656 657 while (i-- > 0) { // expected-warning {{state of variable 'var1' must match at the entry and exit of loop}} 658 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} 659 660 *var1; 661 var1.consume(); 662 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}} 663 } 664 665 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} 666 } 667 668 // Tests if state information is correctly discarded for certain shapes of CFGs. 669 void testSwitchGOTO(void) { 670 int a; 671 672 LABEL0: 673 switch (a) 674 case 0: 675 goto LABEL0; 676 677 goto LABEL0; 678 } 679 680 typedef const int*& IntegerPointerReference; 681 void testIsRValueRefishAndCanonicalType(IntegerPointerReference a) {} 682 683 namespace ContinueICETest { 684 685 bool cond1(); 686 bool cond2(); 687 688 static void foo1() { 689 while (cond1()) { 690 if (cond2()) 691 continue; 692 } 693 } 694 695 static void foo2() { 696 while (true) { 697 if (false) 698 continue; 699 } 700 } 701 702 class runtime_error 703 { 704 public: 705 virtual ~runtime_error(); 706 }; 707 708 void read(bool sf) { 709 while (sf) { 710 if(sf) throw runtime_error(); 711 } 712 } 713 714 } // end namespace ContinueICETest 715 716 717 namespace StatusUseCaseTests { 718 719 class CONSUMABLE(unconsumed) 720 __attribute__((consumable_auto_cast_state)) 721 __attribute__((consumable_set_state_on_read)) 722 Status { 723 int code; 724 725 public: 726 static Status OK; 727 728 Status() RETURN_TYPESTATE(consumed); 729 Status(int c) RETURN_TYPESTATE(unconsumed); 730 731 Status(const Status &other); 732 Status(Status &&other); 733 734 Status& operator=(const Status &other) CALLABLE_WHEN("unknown", "consumed"); 735 Status& operator=(Status &&other) CALLABLE_WHEN("unknown", "consumed"); 736 737 bool operator==(const Status &other) const SET_TYPESTATE(consumed); 738 739 bool check() const SET_TYPESTATE(consumed); 740 void ignore() const SET_TYPESTATE(consumed); 741 // Status& markAsChecked() { return *this; } 742 743 void clear() CALLABLE_WHEN("unknown", "consumed") SET_TYPESTATE(consumed); 744 745 ~Status() CALLABLE_WHEN("unknown", "consumed"); 746 747 operator bool() const; // Will not consume the object. 748 }; 749 750 751 bool cond(); 752 Status doSomething(); 753 void handleStatus(const Status& s RETURN_TYPESTATE(consumed)); 754 void handleStatusRef(Status& s); 755 void handleStatusPtr(Status* s); 756 void handleStatusUnmarked(const Status& s); 757 758 void log(const char* msg); 759 void fail() __attribute__((noreturn)); 760 void checkStat(const Status& s); 761 762 763 void testSimpleTemporaries0() { 764 doSomething(); // expected-warning {{invalid invocation of method '~Status' on a temporary object while it is in the 'unconsumed' state}} 765 } 766 767 void testSimpleTemporaries1() { 768 doSomething().ignore(); 769 } 770 771 void testSimpleTemporaries2() { 772 handleStatus(doSomething()); 773 } 774 775 void testSimpleTemporaries3() { 776 Status s = doSomething(); 777 } // expected-warning {{invalid invocation of method '~Status' on object 's' while it is in the 'unconsumed' state}} 778 779 void testTemporariesWithControlFlow(bool a) { 780 bool b = false || doSomething(); // expected-warning {{invalid invocation of method '~Status' on a temporary object while it is in the 'unconsumed' state}} 781 } 782 783 Status testSimpleTemporariesReturn0() { 784 return doSomething(); 785 } 786 787 Status testSimpleTemporariesReturn1() { 788 Status s = doSomething(); 789 return s; 790 } 791 792 void testSimpleTemporaries4() { 793 Status s = doSomething(); 794 s.check(); 795 } 796 797 void testSimpleTemporaries5() { 798 Status s = doSomething(); 799 s.clear(); // expected-warning {{invalid invocation of method 'clear' on object 's' while it is in the 'unconsumed' state}} 800 } 801 802 void testSimpleTemporaries6() { 803 Status s1 = doSomething(); 804 handleStatus(s1); 805 806 Status s2 = doSomething(); 807 handleStatusRef(s2); 808 809 Status s3 = doSomething(); 810 handleStatusPtr(&s3); 811 812 Status s4 = doSomething(); 813 handleStatusUnmarked(s4); 814 } 815 816 void testSimpleTemporaries7() { 817 Status s; 818 s = doSomething(); 819 } // expected-warning {{invalid invocation of method '~Status' on object 's' while it is in the 'unconsumed' state}} 820 821 void testTemporariesWithConditionals0() { 822 int a; 823 824 Status s = doSomething(); 825 if (cond()) a = 0; 826 else a = 1; 827 } // expected-warning {{invalid invocation of method '~Status' on object 's' while it is in the 'unconsumed' state}} 828 829 void testTemporariesWithConditionals1() { 830 int a; 831 832 Status s = doSomething(); 833 if (cond()) a = 0; 834 else a = 1; 835 s.ignore(); 836 } 837 838 void testTemporariesWithConditionals2() { 839 int a; 840 841 Status s = doSomething(); 842 s.ignore(); 843 if (cond()) a = 0; 844 else a = 1; 845 } 846 847 void testTemporariesWithConditionals3() { 848 Status s = doSomething(); 849 if (cond()) { 850 s.check(); 851 } 852 } 853 854 void testTemporariesAndConstructors0() { 855 Status s(doSomething()); // Test the copy constructor. 856 s.check(); 857 } 858 859 void testTemporariesAndConstructors1F() { 860 Status s1 = doSomething(); // Test the copy constructor. 861 Status s2 = s1; 862 } // expected-warning {{invalid invocation of method '~Status' on object 's2' while it is in the 'unconsumed' state}} 863 864 void testTemporariesAndConstructors1S() { 865 Status s1 = doSomething(); // Test the copy constructor. 866 Status s2(s1); 867 s2.check(); 868 } 869 870 void testTemporariesAndConstructors2F() { 871 // Test the move constructor. 872 Status s1 = doSomething(); 873 Status s2 = static_cast<Status&&>(s1); 874 } // expected-warning {{invalid invocation of method '~Status' on object 's2' while it is in the 'unconsumed' state}} 875 876 void testTemporariesAndConstructors2S() { 877 // Test the move constructor. 878 Status s1 = doSomething(); 879 Status s2 = static_cast<Status&&>(s1); 880 s2.check(); 881 } 882 883 void testTemporariesAndOperators0F() { 884 // Test the assignment operator. 885 Status s1 = doSomething(); 886 Status s2; 887 s2 = s1; 888 } // expected-warning {{invalid invocation of method '~Status' on object 's2' while it is in the 'unconsumed' state}} 889 890 void testTemporariesAndOperators0S() { 891 // Test the assignment operator. 892 Status s1 = doSomething(); 893 Status s2; 894 s2 = s1; 895 s2.check(); 896 } 897 898 void testTemporariesAndOperators1F() { 899 // Test the move assignment operator. 900 Status s1 = doSomething(); 901 Status s2; 902 s2 = static_cast<Status&&>(s1); 903 } // expected-warning {{invalid invocation of method '~Status' on object 's2' while it is in the 'unconsumed' state}} 904 905 void testTemporariesAndOperators1S() { 906 // Test the move assignment operator. 907 Status s1 = doSomething(); 908 Status s2; 909 s2 = static_cast<Status&&>(s1); 910 s2.check(); 911 } 912 913 void testTemporariesAndOperators2() { 914 Status s1 = doSomething(); 915 Status s2 = doSomething(); 916 s1 = s2; // expected-warning {{invalid invocation of method 'operator=' on object 's1' while it is in the 'unconsumed' state}} 917 s1.check(); 918 s2.check(); 919 } 920 921 Status testReturnAutocast() { 922 Status s = doSomething(); 923 s.check(); // consume s 924 return s; // should autocast back to unconsumed 925 } 926 927 928 namespace TestParens { 929 930 void test3() { 931 checkStat((doSomething())); 932 } 933 934 void test4() { 935 Status s = (doSomething()); 936 s.check(); 937 } 938 939 void test5() { 940 (doSomething()).check(); 941 } 942 943 void test6() { 944 if ((doSomething()) == Status::OK) 945 return; 946 } 947 948 } // end namespace TestParens 949 950 } // end namespace InitializerAssertionFailTest 951 952 953 namespace std { 954 void move(); 955 template<class T> 956 T &&move(T&); 957 958 namespace __1 { 959 void move(); 960 template<class T> 961 T &&move(T&); 962 } 963 } 964 965 namespace PR18260 { 966 class X { 967 public: 968 void move(); 969 } x; 970 971 void test() { 972 x.move(); 973 std::move(); 974 std::move(x); // expected-warning {{ignoring return value}} 975 std::__1::move(); 976 std::__1::move(x); 977 } 978 } // end namespace PR18260 979 980