1 #define MOZ_NONHEAP_CLASS __attribute__((annotate("moz_nonheap_class"))) 2 #define MOZ_STACK_CLASS __attribute__((annotate("moz_stack_class"))) 3 #include <stddef.h> 4 5 struct MOZ_NONHEAP_CLASS NonHeap { 6 int i; operator newNonHeap7 void *operator new(size_t x) throw() { return 0; } operator newNonHeap8 void *operator new(size_t blah, char *buffer) { return buffer; } 9 }; 10 11 template <class T> 12 struct MOZ_NONHEAP_CLASS TemplateClass { 13 T i; 14 }; 15 gobble(void *)16void gobble(void *) { } 17 misuseNonHeapClass(int len)18void misuseNonHeapClass(int len) { 19 NonHeap valid; 20 NonHeap alsoValid[2]; 21 static NonHeap validStatic; 22 static NonHeap alsoValidStatic[2]; 23 24 gobble(&valid); 25 gobble(&validStatic); 26 gobble(&alsoValid[0]); 27 28 gobble(new NonHeap); // expected-error {{variable of type 'NonHeap' is not valid on the heap}} expected-note {{value incorrectly allocated on the heap}} 29 gobble(new NonHeap[10]); // expected-error {{variable of type 'NonHeap' is not valid on the heap}} expected-note {{value incorrectly allocated on the heap}} 30 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}} 31 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}} 32 33 char buffer[sizeof(NonHeap)]; 34 gobble(new (buffer) NonHeap); 35 } 36 37 NonHeap validStatic; 38 struct RandomClass { 39 NonHeap nonstaticMember; // expected-note {{'RandomClass' is a non-heap type because member 'nonstaticMember' is a non-heap type 'NonHeap'}} 40 static NonHeap staticMember; 41 }; 42 struct MOZ_NONHEAP_CLASS RandomNonHeapClass { 43 NonHeap nonstaticMember; 44 static NonHeap staticMember; 45 }; 46 47 struct BadInherit : NonHeap {}; // expected-note {{'BadInherit' is a non-heap type because it inherits from a non-heap type 'NonHeap'}} 48 struct MOZ_NONHEAP_CLASS GoodInherit : NonHeap {}; 49 useStuffWrongly()50void useStuffWrongly() { 51 gobble(new BadInherit); // expected-error {{variable of type 'BadInherit' is not valid on the heap}} expected-note {{value incorrectly allocated on the heap}} 52 gobble(new RandomClass); // expected-error {{variable of type 'RandomClass' is not valid on the heap}} expected-note {{value incorrectly allocated on the heap}} 53 } 54 55 // Stack class overrides non-heap typees. 56 struct MOZ_STACK_CLASS StackClass {}; 57 struct MOZ_NONHEAP_CLASS InferredStackClass : GoodInherit { 58 NonHeap nonstaticMember; 59 StackClass stackClass; // expected-note {{'InferredStackClass' is a stack type because member 'stackClass' is a stack type 'StackClass'}} 60 }; 61 62 InferredStackClass global; // expected-error {{variable of type 'InferredStackClass' only valid on the stack}} expected-note {{value incorrectly allocated in a global variable}} 63