michael@0: #define MOZ_NONHEAP_CLASS __attribute__((annotate("moz_nonheap_class"))) michael@0: #define MOZ_HEAP_ALLOCATOR \ michael@0: _Pragma("GCC diagnostic push") \ michael@0: _Pragma("GCC diagnostic ignored \"-Wgcc-compat\"") \ michael@0: __attribute__((annotate("moz_heap_allocator"))) \ michael@0: _Pragma("GCC diagnostic pop") michael@0: michael@0: #include michael@0: #include michael@0: michael@0: struct MOZ_NONHEAP_CLASS X { michael@0: }; michael@0: michael@0: void *operator new(size_t x, int qual) MOZ_HEAP_ALLOCATOR { michael@0: return ::operator new(x); michael@0: } michael@0: michael@0: template michael@0: T *customAlloc() MOZ_HEAP_ALLOCATOR { michael@0: T *arg = static_cast(malloc(sizeof(T))); michael@0: return new (arg) T(); michael@0: } michael@0: michael@0: template michael@0: void misuseX(T q) { michael@0: X *foo = customAlloc(); // expected-error {{variable of type 'X' is not valid on the heap}} michael@0: X *foo2 = new (100) X(); // expected-error {{variable of type 'X' is not valid on the heap}} michael@0: }