summaryrefslogtreecommitdiffstats
path: root/build/clang-plugin/tests/TestNonHeapClass.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'build/clang-plugin/tests/TestNonHeapClass.cpp')
-rw-r--r--build/clang-plugin/tests/TestNonHeapClass.cpp62
1 files changed, 62 insertions, 0 deletions
diff --git a/build/clang-plugin/tests/TestNonHeapClass.cpp b/build/clang-plugin/tests/TestNonHeapClass.cpp
new file mode 100644
index 0000000000..26fe6404e0
--- /dev/null
+++ b/build/clang-plugin/tests/TestNonHeapClass.cpp
@@ -0,0 +1,62 @@
+#define MOZ_NONHEAP_CLASS __attribute__((annotate("moz_nonheap_class")))
+#define MOZ_STACK_CLASS __attribute__((annotate("moz_stack_class")))
+#include <stddef.h>
+
+struct MOZ_NONHEAP_CLASS NonHeap {
+ int i;
+ void *operator new(size_t x) throw() { return 0; }
+ void *operator new(size_t blah, char *buffer) { return buffer; }
+};
+
+template <class T>
+struct MOZ_NONHEAP_CLASS TemplateClass {
+ T i;
+};
+
+void gobble(void *) { }
+
+void misuseNonHeapClass(int len) {
+ NonHeap valid;
+ NonHeap alsoValid[2];
+ static NonHeap validStatic;
+ static NonHeap alsoValidStatic[2];
+
+ gobble(&valid);
+ gobble(&validStatic);
+ gobble(&alsoValid[0]);
+
+ gobble(new NonHeap); // expected-error {{variable of type 'NonHeap' is not valid on the heap}} expected-note {{value incorrectly allocated on the heap}}
+ gobble(new NonHeap[10]); // expected-error {{variable of type 'NonHeap' is not valid on the heap}} expected-note {{value incorrectly allocated on the heap}}
+ gobble(new TemplateClass<int>); // expected-error {{variable of type 'TemplateClass<int>' is not valid on the heap}} expected-note {{value incorrectly allocated on the heap}}
+ gobble(len <= 5 ? &valid : new NonHeap); // expected-error {{variable of type 'NonHeap' is not valid on the heap}} expected-note {{value incorrectly allocated on the heap}}
+
+ char buffer[sizeof(NonHeap)];
+ gobble(new (buffer) NonHeap);
+}
+
+NonHeap validStatic;
+struct RandomClass {
+ NonHeap nonstaticMember; // expected-note {{'RandomClass' is a non-heap type because member 'nonstaticMember' is a non-heap type 'NonHeap'}}
+ static NonHeap staticMember;
+};
+struct MOZ_NONHEAP_CLASS RandomNonHeapClass {
+ NonHeap nonstaticMember;
+ static NonHeap staticMember;
+};
+
+struct BadInherit : NonHeap {}; // expected-note {{'BadInherit' is a non-heap type because it inherits from a non-heap type 'NonHeap'}}
+struct MOZ_NONHEAP_CLASS GoodInherit : NonHeap {};
+
+void useStuffWrongly() {
+ gobble(new BadInherit); // expected-error {{variable of type 'BadInherit' is not valid on the heap}} expected-note {{value incorrectly allocated on the heap}}
+ gobble(new RandomClass); // expected-error {{variable of type 'RandomClass' is not valid on the heap}} expected-note {{value incorrectly allocated on the heap}}
+}
+
+// Stack class overrides non-heap typees.
+struct MOZ_STACK_CLASS StackClass {};
+struct MOZ_NONHEAP_CLASS InferredStackClass : GoodInherit {
+ NonHeap nonstaticMember;
+ StackClass stackClass; // expected-note {{'InferredStackClass' is a stack type because member 'stackClass' is a stack type 'StackClass'}}
+};
+
+InferredStackClass global; // expected-error {{variable of type 'InferredStackClass' only valid on the stack}} expected-note {{value incorrectly allocated in a global variable}}