|
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; |
|
7 void *operator new(size_t x) { return 0; } |
|
8 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 |
|
16 void gobble(void *) { } |
|
17 |
|
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}} |
|
29 gobble(new NonHeap[10]); // expected-error {{variable of type 'NonHeap' is not valid on the heap}} |
|
30 gobble(new TemplateClass<int>); // expected-error {{variable of type 'TemplateClass<int>' is not valid on the heap}} |
|
31 gobble(len <= 5 ? &valid : new NonHeap); // expected-error {{variable of type 'NonHeap' is not valid 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 class because member 'nonstaticMember' is a non-heap class '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 class because it inherits from a non-heap class 'NonHeap'}} |
|
48 struct MOZ_NONHEAP_CLASS GoodInherit : NonHeap {}; |
|
49 |
|
50 void useStuffWrongly() { |
|
51 gobble(new BadInherit); // expected-error {{variable of type 'BadInherit' is not valid on the heap}} |
|
52 gobble(new RandomClass); // expected-error {{variable of type 'RandomClass' is not valid on the heap}} |
|
53 } |
|
54 |
|
55 // Stack class overrides non-heap classes. |
|
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 class because member 'stackClass' is a stack class 'StackClass'}} |
|
60 }; |
|
61 |
|
62 InferredStackClass global; // expected-error {{variable of type 'InferredStackClass' only valid on the stack}} |