#define MOZ_STACK_CLASS __attribute__((annotate("moz_stack_class"))) #include struct MOZ_STACK_CLASS Stack { int i; void *operator new(size_t x) throw() { return 0; } void *operator new(size_t blah, char *buffer) { return buffer; } }; template struct MOZ_STACK_CLASS TemplateClass { T i; }; void gobble(void *) { } void misuseStackClass(int len) { Stack valid; Stack alsoValid[2]; static Stack notValid; // expected-error {{variable of type 'Stack' only valid on the stack}} expected-note {{value incorrectly allocated in a global variable}} static Stack alsoNotValid[2]; // expected-error-re {{variable of type 'Stack{{ ?}}[2]' only valid on the stack}} expected-note-re {{'Stack{{ ?}}[2]' is a stack type because it is an array of stack type 'Stack'}} expected-note {{value incorrectly allocated in a global variable}} gobble(&valid); gobble(¬Valid); gobble(&alsoValid[0]); gobble(new Stack); // expected-error {{variable of type 'Stack' only valid on the stack}} expected-note {{value incorrectly allocated on the heap}} gobble(new Stack[10]); // expected-error {{variable of type 'Stack' only valid on the stack}} expected-note {{value incorrectly allocated on the heap}} gobble(new TemplateClass); // expected-error {{variable of type 'TemplateClass' only valid on the stack}} expected-note {{value incorrectly allocated on the heap}} gobble(len <= 5 ? &valid : new Stack); // expected-error {{variable of type 'Stack' only valid on the stack}} expected-note {{value incorrectly allocated on the heap}} char buffer[sizeof(Stack)]; gobble(new (buffer) Stack); } Stack notValid; // expected-error {{variable of type 'Stack' only valid on the stack}} expected-note {{value incorrectly allocated in a global variable}} struct RandomClass { Stack nonstaticMember; // expected-note {{'RandomClass' is a stack type because member 'nonstaticMember' is a stack type 'Stack'}} static Stack staticMember; // expected-error {{variable of type 'Stack' only valid on the stack}} expected-note {{value incorrectly allocated in a global variable}} }; struct MOZ_STACK_CLASS RandomStackClass { Stack nonstaticMember; static Stack staticMember; // expected-error {{variable of type 'Stack' only valid on the stack}} expected-note {{value incorrectly allocated in a global variable}} }; struct BadInherit : Stack {}; // expected-note {{'BadInherit' is a stack type because it inherits from a stack type 'Stack'}} struct MOZ_STACK_CLASS GoodInherit : Stack {}; BadInherit moreInvalid; // expected-error {{variable of type 'BadInherit' only valid on the stack}} expected-note {{value incorrectly allocated in a global variable}} RandomClass evenMoreInvalid; // expected-error {{variable of type 'RandomClass' only valid on the stack}} expected-note {{value incorrectly allocated in a global variable}}