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