diff options
Diffstat (limited to 'test/SemaCXX/warn-consumed-analysis.cpp')
-rw-r--r-- | test/SemaCXX/warn-consumed-analysis.cpp | 795 |
1 files changed, 795 insertions, 0 deletions
diff --git a/test/SemaCXX/warn-consumed-analysis.cpp b/test/SemaCXX/warn-consumed-analysis.cpp new file mode 100644 index 0000000..64fdc00 --- /dev/null +++ b/test/SemaCXX/warn-consumed-analysis.cpp @@ -0,0 +1,795 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wconsumed -fcxx-exceptions -std=c++11 %s + +// TODO: Switch to using macros for the expected warnings. + +#define CALLABLE_WHEN(...) __attribute__ ((callable_when(__VA_ARGS__))) +#define CONSUMABLE(state) __attribute__ ((consumable(state))) +#define PARAM_TYPESTATE(state) __attribute__ ((param_typestate(state))) +#define RETURN_TYPESTATE(state) __attribute__ ((return_typestate(state))) +#define SET_TYPESTATE(state) __attribute__ ((set_typestate(state))) +#define TEST_TYPESTATE(state) __attribute__ ((test_typestate(state))) + +typedef decltype(nullptr) nullptr_t; + +template <typename T> +class CONSUMABLE(unconsumed) ConsumableClass { + T var; + +public: + ConsumableClass(); + ConsumableClass(nullptr_t p) RETURN_TYPESTATE(consumed); + ConsumableClass(T val) RETURN_TYPESTATE(unconsumed); + ConsumableClass(ConsumableClass<T> &other); + ConsumableClass(ConsumableClass<T> &&other); + + ConsumableClass<T>& operator=(ConsumableClass<T> &other); + ConsumableClass<T>& operator=(ConsumableClass<T> &&other); + ConsumableClass<T>& operator=(nullptr_t) SET_TYPESTATE(consumed); + + template <typename U> + ConsumableClass<T>& operator=(ConsumableClass<U> &other); + + template <typename U> + ConsumableClass<T>& operator=(ConsumableClass<U> &&other); + + void operator()(int a) SET_TYPESTATE(consumed); + void operator*() const CALLABLE_WHEN("unconsumed"); + void unconsumedCall() const CALLABLE_WHEN("unconsumed"); + void callableWhenUnknown() const CALLABLE_WHEN("unconsumed", "unknown"); + + bool isValid() const TEST_TYPESTATE(unconsumed); + operator bool() const TEST_TYPESTATE(unconsumed); + bool operator!=(nullptr_t) const TEST_TYPESTATE(unconsumed); + bool operator==(nullptr_t) const TEST_TYPESTATE(consumed); + + void constCall() const; + void nonconstCall(); + + void consume() SET_TYPESTATE(consumed); + void unconsume() SET_TYPESTATE(unconsumed); +}; + +class CONSUMABLE(unconsumed) DestructorTester { +public: + DestructorTester() RETURN_TYPESTATE(unconsumed); + DestructorTester(int); + + void operator*() CALLABLE_WHEN("unconsumed"); + + ~DestructorTester() CALLABLE_WHEN("consumed"); +}; + +void baf0(const ConsumableClass<int> var); +void baf1(const ConsumableClass<int> &var); +void baf2(const ConsumableClass<int> *var); + +void baf3(ConsumableClass<int> var); +void baf4(ConsumableClass<int> &var); +void baf5(ConsumableClass<int> *var); +void baf6(ConsumableClass<int> &&var); + +ConsumableClass<int> returnsUnconsumed() { + return ConsumableClass<int>(); // expected-warning {{return value not in expected state; expected 'unconsumed', observed 'consumed'}} +} + +ConsumableClass<int> returnsConsumed() RETURN_TYPESTATE(consumed); +ConsumableClass<int> returnsConsumed() { + return ConsumableClass<int>(); +} + +ConsumableClass<int> returnsUnknown() RETURN_TYPESTATE(unknown); + +void testInitialization() { + ConsumableClass<int> var0; + ConsumableClass<int> var1 = ConsumableClass<int>(); + + var0 = ConsumableClass<int>(); + + *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} + *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}} + + if (var0.isValid()) { + *var0; + *var1; + + } else { + *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} + } +} + +void testDestruction() { + DestructorTester D0(42), D1(42); + + *D0; + *D1; + + DestructorTester D2; + *D2; + + D0.~DestructorTester(); // expected-warning {{invalid invocation of method '~DestructorTester' on object 'D0' while it is in the 'unconsumed' state}} + + return; // expected-warning {{invalid invocation of method '~DestructorTester' on object 'D0' while it is in the 'unconsumed' state}} \ + expected-warning {{invalid invocation of method '~DestructorTester' on object 'D1' while it is in the 'unconsumed' state}} \ + expected-warning {{invalid invocation of method '~DestructorTester' on object 'D2' while it is in the 'unconsumed' state}} +} + +void testTempValue() { + *ConsumableClass<int>(); // expected-warning {{invalid invocation of method 'operator*' on a temporary object while it is in the 'consumed' state}} +} + +void testSimpleRValueRefs() { + ConsumableClass<int> var0; + ConsumableClass<int> var1(42); + + *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} + *var1; + + var0 = static_cast<ConsumableClass<int>&&>(var1); + + *var0; + *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}} +} + +void testIfStmt() { + ConsumableClass<int> var; + + if (var.isValid()) { + *var; + } else { + *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}} + } + + if (!var.isValid()) { + *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}} + } else { + *var; + } + + if (var) { + // Empty + } else { + *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}} + } + + if (var != nullptr) { + // Empty + } else { + *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}} + } + + if (var == nullptr) { + *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}} + } else { + // Empty + } +} + +void testComplexConditionals0() { + ConsumableClass<int> var0, var1, var2; + + if (var0 && var1) { + *var0; + *var1; + + } else { + *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} + *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}} + } + + if (var0 || var1) { + *var0; + *var1; + + } else { + *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} + *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}} + } + + if (var0 && !var1) { + *var0; + *var1; + + } else { + *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} + *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}} + } + + if (var0 || !var1) { + *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} + *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}} + + } else { + *var0; + *var1; + } + + if (!var0 && !var1) { + *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} + *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}} + + } else { + *var0; + *var1; + } + + if (!var0 || !var1) { + *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} + *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}} + + } else { + *var0; + *var1; + } + + if (!(var0 && var1)) { + *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} + *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}} + + } else { + *var0; + *var1; + } + + if (!(var0 || var1)) { + *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} + *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}} + + } else { + *var0; + *var1; + } + + if (var0 && var1 && var2) { + *var0; + *var1; + *var2; + + } else { + *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} + *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}} + *var2; // expected-warning {{invalid invocation of method 'operator*' on object 'var2' while it is in the 'consumed' state}} + } + +#if 0 + // FIXME: Get this test to pass. + if (var0 || var1 || var2) { + *var0; + *var1; + *var2; + + } else { + *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} + *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}} + *var2; // expected-warning {{invalid invocation of method 'operator*' on object 'var2' while it is in the 'consumed' state}} + } +#endif +} + +void testComplexConditionals1() { + ConsumableClass<int> var0, var1, var2; + + // Coerce all variables into the unknown state. + baf4(var0); + baf4(var1); + baf4(var2); + + if (var0 && var1) { + *var0; + *var1; + + } else { + *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}} + *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}} + } + + if (var0 || var1) { + *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}} + *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}} + + } else { + *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} + *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}} + } + + if (var0 && !var1) { + *var0; + *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}} + + } else { + *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}} + *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}} + } + + if (var0 || !var1) { + *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}} + *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}} + + } else { + *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} + *var1; + } + + if (!var0 && !var1) { + *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} + *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}} + + } else { + *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}} + *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}} + } + + if (!(var0 || var1)) { + *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} + *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}} + + } else { + *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}} + *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}} + } + + if (!var0 || !var1) { + *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}} + *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}} + + } else { + *var0; + *var1; + } + + if (!(var0 && var1)) { + *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}} + *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}} + + } else { + *var0; + *var1; + } + + if (var0 && var1 && var2) { + *var0; + *var1; + *var2; + + } else { + *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}} + *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}} + *var2; // expected-warning {{invalid invocation of method 'operator*' on object 'var2' while it is in the 'unknown' state}} + } + +#if 0 + // FIXME: Get this test to pass. + if (var0 || var1 || var2) { + *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}} + *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}} + *var2; // expected-warning {{invalid invocation of method 'operator*' on object 'var2' while it is in the 'unknown' state}} + + } else { + *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} + *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}} + *var2; // expected-warning {{invalid invocation of method 'operator*' on object 'var2' while it is in the 'consumed' state}} + } +#endif +} + +void testStateChangeInBranch() { + ConsumableClass<int> var; + + // Make var enter the 'unknown' state. + baf4(var); + + if (!var) { + var = ConsumableClass<int>(42); + } + + *var; +} + +void testFunctionParam(ConsumableClass<int> param) { + + if (param.isValid()) { + *param; + } else { + *param; + } + + param = nullptr; + *param; // expected-warning {{invocation of method 'operator*' on object 'param' while it is in the 'consumed' state}} +} + +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'}} + + if (cond) { + Param.consume(); + return; // expected-warning {{parameter 'Param' not in expected state when the function returns: expected 'unconsumed', observed 'consumed'}} + } + + Param.consume(); +} + +void testParamReturnTypestateCaller() { + ConsumableClass<int> var; + + testParamReturnTypestateCallee(true, var); + + *var; +} + +void testParamTypestateCallee(ConsumableClass<int> Param0 PARAM_TYPESTATE(consumed), + ConsumableClass<int> &Param1 PARAM_TYPESTATE(consumed)) { + + *Param0; // expected-warning {{invalid invocation of method 'operator*' on object 'Param0' while it is in the 'consumed' state}} + *Param1; // expected-warning {{invalid invocation of method 'operator*' on object 'Param1' while it is in the 'consumed' state}} +} + +void testParamTypestateCaller() { + ConsumableClass<int> Var0, Var1(42); + + testParamTypestateCallee(Var0, Var1); // expected-warning {{argument not in expected state; expected 'consumed', observed 'unconsumed'}} +} + +void baf3(ConsumableClass<int> var) { + *var; +} + +void baf4(ConsumableClass<int> &var) { + *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'unknown' state}} +} + +void baf6(ConsumableClass<int> &&var) { + *var; +} + +void testCallingConventions() { + ConsumableClass<int> var(42); + + baf0(var); + *var; + + baf1(var); + *var; + + baf2(&var); + *var; + + baf4(var); + *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'unknown' state}} + + var = ConsumableClass<int>(42); + baf5(&var); + *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'unknown' state}} + + var = ConsumableClass<int>(42); + baf6(static_cast<ConsumableClass<int>&&>(var)); + *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}} +} + +void testConstAndNonConstMemberFunctions() { + ConsumableClass<int> var(42); + + var.constCall(); + *var; + + var.nonconstCall(); + *var; +} + +void testFunctionParam0(ConsumableClass<int> param) { + *param; +} + +void testFunctionParam1(ConsumableClass<int> ¶m) { + *param; // expected-warning {{invalid invocation of method 'operator*' on object 'param' while it is in the 'unknown' state}} +} + +void testReturnStates() { + ConsumableClass<int> var; + + var = returnsUnconsumed(); + *var; + + var = returnsConsumed(); + *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}} +} + +void testCallableWhen() { + ConsumableClass<int> var(42); + + *var; + + baf4(var); + + var.callableWhenUnknown(); +} + +void testMoveAsignmentish() { + ConsumableClass<int> var0; + ConsumableClass<long> var1(42); + + *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} + *var1; + + var0 = static_cast<ConsumableClass<long>&&>(var1); + + *var0; + *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}} + + var1 = ConsumableClass<long>(42); + var1 = nullptr; + *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}} +} + +void testConditionalMerge() { + ConsumableClass<int> var; + + if (var.isValid()) { + // Empty + } + + *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}} + + if (var.isValid()) { + // Empty + } else { + // Empty + } + + *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}} +} + +void testSetTypestate() { + ConsumableClass<int> var(42); + + *var; + + var.consume(); + + *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}} + + var.unconsume(); + + *var; +} + +void testConsumes0() { + ConsumableClass<int> var(nullptr); + + *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}} +} + +void testConsumes1() { + ConsumableClass<int> var(42); + + var.unconsumedCall(); + var(6); + + var.unconsumedCall(); // expected-warning {{invalid invocation of method 'unconsumedCall' on object 'var' while it is in the 'consumed' state}} +} + +void testUnreachableBlock() { + ConsumableClass<int> var(42); + + if (var) { + *var; + } else { + *var; + } + + *var; +} + + +void testForLoop1() { + ConsumableClass<int> var0, var1(42); + + for (int i = 0; i < 10; ++i) { // expected-warning {{state of variable 'var1' must match at the entry and exit of loop}} + *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} + + *var1; + var1.consume(); + *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}} + } + + *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} +} + +void testWhileLoop1() { + int i = 10; + + ConsumableClass<int> var0, var1(42); + + while (i-- > 0) { // expected-warning {{state of variable 'var1' must match at the entry and exit of loop}} + *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} + + *var1; + var1.consume(); + *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}} + } + + *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} +} + +typedef const int*& IntegerPointerReference; +void testIsRValueRefishAndCanonicalType(IntegerPointerReference a) {} + +namespace ContinueICETest { + +bool cond1(); +bool cond2(); + +static void foo1() { + while (cond1()) { + if (cond2()) + continue; + } +} + +static void foo2() { + while (true) { + if (false) + continue; + } +} + +class runtime_error +{ +public: + virtual ~runtime_error(); +}; + +void read(bool sf) { + while (sf) { + if(sf) throw runtime_error(); + } +} + +} // end namespace ContinueICETest + + +namespace InitializerAssertionFailTest { + +class CONSUMABLE(unconsumed) Status { + int code; + +public: + Status() RETURN_TYPESTATE(consumed); + Status(int c) RETURN_TYPESTATE(unconsumed); + + Status(const Status &other); + Status(Status &&other); + + Status& operator=(const Status &other) CALLABLE_WHEN("unknown", "consumed"); + Status& operator=(Status &&other) CALLABLE_WHEN("unknown", "consumed"); + + bool check() const SET_TYPESTATE(consumed); + void ignore() const SET_TYPESTATE(consumed); + // Status& markAsChecked() { return *this; } + + void clear() CALLABLE_WHEN("unknown", "consumed") SET_TYPESTATE(consumed); + + ~Status() CALLABLE_WHEN("unknown", "consumed"); +}; + + +bool cond(); +Status doSomething(); +void handleStatus(const Status& s RETURN_TYPESTATE(consumed)); +void handleStatusPtr(const Status* s); + +void testSimpleTemporaries0() { + doSomething(); // expected-warning {{invalid invocation of method '~Status' on a temporary object while it is in the 'unconsumed' state}} +} + +void testSimpleTemporaries1() { + doSomething().ignore(); +} + +void testSimpleTemporaries2() { + handleStatus(doSomething()); +} + +void testSimpleTemporaries3() { + Status s = doSomething(); +} // expected-warning {{invalid invocation of method '~Status' on object 's' while it is in the 'unconsumed' state}} + +void testSimpleTemporaries4() { + Status s = doSomething(); + s.check(); +} + +void testSimpleTemporaries5() { + Status s = doSomething(); + s.clear(); // expected-warning {{invalid invocation of method 'clear' on object 's' while it is in the 'unconsumed' state}} +} + +void testSimpleTemporaries6() { + Status s = doSomething(); + handleStatus(s); +} + +void testSimpleTemporaries7() { + Status s; + s = doSomething(); +} // expected-warning {{invalid invocation of method '~Status' on object 's' while it is in the 'unconsumed' state}} + +void testTemporariesWithConditionals0() { + int a; + + Status s = doSomething(); + if (cond()) a = 0; + else a = 1; +} // expected-warning {{invalid invocation of method '~Status' on object 's' while it is in the 'unconsumed' state}} + +void testTemporariesWithConditionals1() { + int a; + + Status s = doSomething(); + if (cond()) a = 0; + else a = 1; + s.ignore(); +} + +void testTemporariesWithConditionals2() { + int a; + + Status s = doSomething(); + s.ignore(); + if (cond()) a = 0; + else a = 1; +} + +void testTemporariesWithConditionals3() { + Status s = doSomething(); + if (cond()) { + s.check(); + } +} + +void testTemporariesAndConstructors0() { + Status s(doSomething()); + s.check(); +} + +void testTemporariesAndConstructors1() { + // Test the copy constructor. + + Status s1 = doSomething(); + Status s2(s1); + s2.check(); +} // expected-warning {{invalid invocation of method '~Status' on object 's1' while it is in the 'unconsumed' state}} + +void testTemporariesAndConstructors2() { + // Test the move constructor. + + Status s1 = doSomething(); + Status s2(static_cast<Status&&>(s1)); + s2.check(); +} + +void testTemporariesAndOperators0() { + // Test the assignment operator. + + Status s1 = doSomething(); + Status s2; + s2 = s1; + s2.check(); +} // expected-warning {{invalid invocation of method '~Status' on object 's1' while it is in the 'unconsumed' state}} + +void testTemporariesAndOperators1() { + // Test the move assignment operator. + + Status s1 = doSomething(); + Status s2; + s2 = static_cast<Status&&>(s1); + s2.check(); +} + +void testTemporariesAndOperators2() { + Status s1 = doSomething(); + Status s2 = doSomething(); + s1 = s2; // expected-warning {{invalid invocation of method 'operator=' on object 's1' while it is in the 'unconsumed' state}} + s1.check(); + s2.check(); +} + +} // end namespace InitializerAssertionFailTest + |