diff options
| author | DeLesley Hutchins <delesley@google.com> | 2013-09-03 20:11:38 +0000 |
|---|---|---|
| committer | DeLesley Hutchins <delesley@google.com> | 2013-09-03 20:11:38 +0000 |
| commit | fc368259af1a580b1843174cae3067d1b3c9aafc (patch) | |
| tree | 2732d2c5da4cb77df8c39009f0077f78387c6382 /clang/test | |
| parent | 362bf98ec68b63f8abcd347e48db2551436de75d (diff) | |
| download | bcm5719-llvm-fc368259af1a580b1843174cae3067d1b3c9aafc.tar.gz bcm5719-llvm-fc368259af1a580b1843174cae3067d1b3c9aafc.zip | |
Consumed analysis: add return_typestate attribute.
Patch by chris.wailes@gmail.com
Functions can now declare what state the consumable type the are returning will
be in. This is then used on the caller side and checked on the callee side.
Constructors now use this attribute instead of the 'consumes' attribute.
llvm-svn: 189843
Diffstat (limited to 'clang/test')
| -rw-r--r-- | clang/test/SemaCXX/warn-consumed-analysis-strict.cpp | 8 | ||||
| -rw-r--r-- | clang/test/SemaCXX/warn-consumed-analysis.cpp | 29 | ||||
| -rw-r--r-- | clang/test/SemaCXX/warn-consumed-parsing.cpp | 33 |
3 files changed, 52 insertions, 18 deletions
diff --git a/clang/test/SemaCXX/warn-consumed-analysis-strict.cpp b/clang/test/SemaCXX/warn-consumed-analysis-strict.cpp index 499ba009bdd..1bc604de479 100644 --- a/clang/test/SemaCXX/warn-consumed-analysis-strict.cpp +++ b/clang/test/SemaCXX/warn-consumed-analysis-strict.cpp @@ -3,6 +3,7 @@ #define CALLABLE_WHEN_UNCONSUMED __attribute__ ((callable_when_unconsumed)) #define CONSUMABLE __attribute__ ((consumable)) #define CONSUMES __attribute__ ((consumes)) +#define RETURN_TYPESTATE(State) __attribute__ ((return_typestate(State))) #define TESTS_UNCONSUMED __attribute__ ((tests_unconsumed)) #define TEST_VAR(Var) Var.isValid() @@ -15,9 +16,10 @@ class CONSUMABLE ConsumableClass { public: ConsumableClass(); - ConsumableClass(T val); - ConsumableClass(ConsumableClass<T> &other); - ConsumableClass(ConsumableClass<T> &&other); + ConsumableClass(nullptr_t p) RETURN_TYPESTATE(consumed); + ConsumableClass(T val) RETURN_TYPESTATE(unconsumed); + ConsumableClass(ConsumableClass<T> &other) RETURN_TYPESTATE(unconsumed); + ConsumableClass(ConsumableClass<T> &&other) RETURN_TYPESTATE(unconsumed); ConsumableClass<T>& operator=(ConsumableClass<T> &other); ConsumableClass<T>& operator=(ConsumableClass<T> &&other); diff --git a/clang/test/SemaCXX/warn-consumed-analysis.cpp b/clang/test/SemaCXX/warn-consumed-analysis.cpp index d4387fc29de..53a29b128d9 100644 --- a/clang/test/SemaCXX/warn-consumed-analysis.cpp +++ b/clang/test/SemaCXX/warn-consumed-analysis.cpp @@ -3,6 +3,7 @@ #define CALLABLE_WHEN_UNCONSUMED __attribute__ ((callable_when_unconsumed)) #define CONSUMABLE __attribute__ ((consumable)) #define CONSUMES __attribute__ ((consumes)) +#define RETURN_TYPESTATE(State) __attribute__ ((return_typestate(State))) #define TESTS_UNCONSUMED __attribute__ ((tests_unconsumed)) typedef decltype(nullptr) nullptr_t; @@ -13,10 +14,10 @@ class CONSUMABLE ConsumableClass { public: ConsumableClass(); - ConsumableClass(nullptr_t p) CONSUMES; - ConsumableClass(T val); - ConsumableClass(ConsumableClass<T> &other); - ConsumableClass(ConsumableClass<T> &&other); + ConsumableClass(nullptr_t p) RETURN_TYPESTATE(consumed); + ConsumableClass(T val) RETURN_TYPESTATE(unconsumed); + ConsumableClass(ConsumableClass<T> &other) RETURN_TYPESTATE(unconsumed); + ConsumableClass(ConsumableClass<T> &&other) RETURN_TYPESTATE(unconsumed); ConsumableClass<T>& operator=(ConsumableClass<T> &other); ConsumableClass<T>& operator=(ConsumableClass<T> &&other); @@ -48,6 +49,16 @@ void baf2(const ConsumableClass<int> *var); void baf3(ConsumableClass<int> &&var); +ConsumableClass<int> returnsUnconsumed() RETURN_TYPESTATE(unconsumed); +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>(); +} + void testInitialization() { ConsumableClass<int> var0; ConsumableClass<int> var1 = ConsumableClass<int>(); @@ -253,6 +264,16 @@ void testCallingConventions() { *var; // expected-warning {{invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}} } +void testReturnStates() { + ConsumableClass<int> var; + + var = returnsUnconsumed(); + *var; + + var = returnsConsumed(); + *var; // expected-warning {{invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}} +} + void testMoveAsignmentish() { ConsumableClass<int> var0; ConsumableClass<long> var1(42); diff --git a/clang/test/SemaCXX/warn-consumed-parsing.cpp b/clang/test/SemaCXX/warn-consumed-parsing.cpp index ae71e29dc79..674197f6e02 100644 --- a/clang/test/SemaCXX/warn-consumed-parsing.cpp +++ b/clang/test/SemaCXX/warn-consumed-parsing.cpp @@ -1,21 +1,29 @@ // RUN: %clang_cc1 -fsyntax-only -verify -Wconsumed -std=c++11 %s -#define CONSUMABLE __attribute__ ((consumable)) -#define CONSUMES __attribute__ ((consumes)) -#define TESTS_UNCONSUMED __attribute__ ((tests_unconsumed)) -#define CALLABLE_WHEN_UNCONSUMED __attribute__ ((callable_when_unconsumed)) +#define CALLABLE_WHEN_UNCONSUMED __attribute__ ((callable_when_unconsumed)) +#define CONSUMABLE __attribute__ ((consumable)) +#define CONSUMES __attribute__ ((consumes)) +#define RETURN_TYPESTATE(State) __attribute__ ((return_typestate(State))) +#define TESTS_UNCONSUMED __attribute__ ((tests_unconsumed)) + +// FIXME: This warning is not generated if it appears bellow the AttrTester0 +// class declaration. Why? +int returnTypestateForUnconsumable() RETURN_TYPESTATE(consumed); // expected-warning {{return state set for an unconsumable type 'int'}} +int returnTypestateForUnconsumable() { + return 0; +} class AttrTester0 { - void Consumes() __attribute__ ((consumes(42))); // expected-error {{attribute takes no arguments}} - bool TestsUnconsumed() __attribute__ ((tests_unconsumed(42))); // expected-error {{attribute takes no arguments}} - void CallableWhenUnconsumed() - __attribute__ ((callable_when_unconsumed(42))); // expected-error {{attribute takes no arguments}} + void consumes() __attribute__ ((consumes(42))); // expected-error {{attribute takes no arguments}} + bool testsUnconsumed() __attribute__ ((tests_unconsumed(42))); // expected-error {{attribute takes no arguments}} + void callableWhenUnconsumed() __attribute__ ((callable_when_unconsumed(42))); // expected-error {{attribute takes no arguments}} }; int var0 CONSUMES; // expected-warning {{'consumes' attribute only applies to methods}} int var1 TESTS_UNCONSUMED; // expected-warning {{'tests_unconsumed' attribute only applies to methods}} int var2 CALLABLE_WHEN_UNCONSUMED; // expected-warning {{'callable_when_unconsumed' attribute only applies to methods}} int var3 CONSUMABLE; // expected-warning {{'consumable' attribute only applies to classes}} +int var4 RETURN_TYPESTATE(consumed); // expected-warning {{'return_typestate' attribute only applies to functions}} void function0() CONSUMES; // expected-warning {{'consumes' attribute only applies to methods}} void function1() TESTS_UNCONSUMED; // expected-warning {{'tests_unconsumed' attribute only applies to methods}} @@ -28,8 +36,11 @@ class CONSUMABLE AttrTester1 { bool testsUnconsumed() TESTS_UNCONSUMED; }; +AttrTester1 returnTypestateTester0() RETURN_TYPESTATE(not_a_state); // expected-warning {{unknown consumed analysis state 'not_a_state'}} +AttrTester1 returnTypestateTester1() RETURN_TYPESTATE(42); // expected-error {{'return_typestate' attribute requires an identifier}} + class AttrTester2 { - void callableWhenUnconsumed() CALLABLE_WHEN_UNCONSUMED; // expected-warning {{consumed analysis attribute is attached to class 'AttrTester2' which isn't marked as consumable}} - void consumes() CONSUMES; // expected-warning {{consumed analysis attribute is attached to class 'AttrTester2' which isn't marked as consumable}} - bool testsUnconsumed() TESTS_UNCONSUMED; // expected-warning {{consumed analysis attribute is attached to class 'AttrTester2' which isn't marked as consumable}} + void callableWhenUnconsumed() CALLABLE_WHEN_UNCONSUMED; // expected-warning {{consumed analysis attribute is attached to member of class 'AttrTester2' which isn't marked as consumable}} + void consumes() CONSUMES; // expected-warning {{consumed analysis attribute is attached to member of class 'AttrTester2' which isn't marked as consumable}} + bool testsUnconsumed() TESTS_UNCONSUMED; // expected-warning {{consumed analysis attribute is attached to member of class 'AttrTester2' which isn't marked as consumable}} }; |

