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 *)16 void gobble(void *) { }
17 
misuseNonHeapClass(int len)18 void 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()50 void 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