1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/build/clang-plugin/tests/TestNonHeapClass.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,62 @@ 1.4 +#define MOZ_NONHEAP_CLASS __attribute__((annotate("moz_nonheap_class"))) 1.5 +#define MOZ_STACK_CLASS __attribute__((annotate("moz_stack_class"))) 1.6 +#include <stddef.h> 1.7 + 1.8 +struct MOZ_NONHEAP_CLASS NonHeap { 1.9 + int i; 1.10 + void *operator new(size_t x) { return 0; } 1.11 + void *operator new(size_t blah, char *buffer) { return buffer; } 1.12 +}; 1.13 + 1.14 +template <class T> 1.15 +struct MOZ_NONHEAP_CLASS TemplateClass { 1.16 + T i; 1.17 +}; 1.18 + 1.19 +void gobble(void *) { } 1.20 + 1.21 +void misuseNonHeapClass(int len) { 1.22 + NonHeap valid; 1.23 + NonHeap alsoValid[2]; 1.24 + static NonHeap validStatic; 1.25 + static NonHeap alsoValidStatic[2]; 1.26 + 1.27 + gobble(&valid); 1.28 + gobble(&validStatic); 1.29 + gobble(&alsoValid[0]); 1.30 + 1.31 + gobble(new NonHeap); // expected-error {{variable of type 'NonHeap' is not valid on the heap}} 1.32 + gobble(new NonHeap[10]); // expected-error {{variable of type 'NonHeap' is not valid on the heap}} 1.33 + gobble(new TemplateClass<int>); // expected-error {{variable of type 'TemplateClass<int>' is not valid on the heap}} 1.34 + gobble(len <= 5 ? &valid : new NonHeap); // expected-error {{variable of type 'NonHeap' is not valid on the heap}} 1.35 + 1.36 + char buffer[sizeof(NonHeap)]; 1.37 + gobble(new (buffer) NonHeap); 1.38 +} 1.39 + 1.40 +NonHeap validStatic; 1.41 +struct RandomClass { 1.42 + NonHeap nonstaticMember; // expected-note {{'RandomClass' is a non-heap class because member 'nonstaticMember' is a non-heap class 'NonHeap'}} 1.43 + static NonHeap staticMember; 1.44 +}; 1.45 +struct MOZ_NONHEAP_CLASS RandomNonHeapClass { 1.46 + NonHeap nonstaticMember; 1.47 + static NonHeap staticMember; 1.48 +}; 1.49 + 1.50 +struct BadInherit : NonHeap {}; // expected-note {{'BadInherit' is a non-heap class because it inherits from a non-heap class 'NonHeap'}} 1.51 +struct MOZ_NONHEAP_CLASS GoodInherit : NonHeap {}; 1.52 + 1.53 +void useStuffWrongly() { 1.54 + gobble(new BadInherit); // expected-error {{variable of type 'BadInherit' is not valid on the heap}} 1.55 + gobble(new RandomClass); // expected-error {{variable of type 'RandomClass' is not valid on the heap}} 1.56 +} 1.57 + 1.58 +// Stack class overrides non-heap classes. 1.59 +struct MOZ_STACK_CLASS StackClass {}; 1.60 +struct MOZ_NONHEAP_CLASS InferredStackClass : GoodInherit { 1.61 + NonHeap nonstaticMember; 1.62 + StackClass stackClass; // expected-note {{'InferredStackClass' is a stack class because member 'stackClass' is a stack class 'StackClass'}} 1.63 +}; 1.64 + 1.65 +InferredStackClass global; // expected-error {{variable of type 'InferredStackClass' only valid on the stack}}