1 #define MOZ_TEMPORARY_CLASS __attribute__((annotate("moz_temporary_class"))) 2 #define MOZ_IMPLICIT __attribute__((annotate("moz_implicit"))) 3 4 #include <stddef.h> 5 6 struct MOZ_TEMPORARY_CLASS Temporary { 7 int i; TemporaryTemporary8 Temporary() {} TemporaryTemporary9 MOZ_IMPLICIT Temporary(int a) {} TemporaryTemporary10 Temporary(int a, int b) {} operator newTemporary11 void *operator new(size_t x) throw() { return 0; } operator newTemporary12 void *operator new(size_t blah, char *buffer) { return buffer; } 13 }; 14 15 template <class T> 16 struct MOZ_TEMPORARY_CLASS TemplateClass { 17 T i; 18 }; 19 gobble(void *)20void gobble(void *) { } 21 gobbleref(const Temporary &)22void gobbleref(const Temporary&) { } 23 24 template <class T> gobbleanyref(const T &)25void gobbleanyref(const T&) { } 26 misuseNonTemporaryClass(int len)27void misuseNonTemporaryClass(int len) { 28 // All of these should error. 29 Temporary invalid; // expected-error {{variable of type 'Temporary' is only valid as a temporary}} expected-note {{value incorrectly allocated in an automatic variable}} 30 Temporary alsoInvalid[2]; // expected-error {{variable of type 'Temporary [2]' is only valid as a temporary}} expected-note {{value incorrectly allocated in an automatic variable}} expected-note {{'Temporary [2]' is a temporary type because it is an array of temporary type 'Temporary'}} 31 static Temporary invalidStatic; // expected-error {{variable of type 'Temporary' is only valid as a temporary}} expected-note {{value incorrectly allocated in a global variable}} 32 static Temporary alsoInvalidStatic[2]; // expected-error {{variable of type 'Temporary [2]' is only valid as a temporary}} expected-note {{value incorrectly allocated in a global variable}} expected-note {{'Temporary [2]' is a temporary type because it is an array of temporary type 'Temporary'}} 33 34 gobble(&invalid); 35 gobble(&invalidStatic); 36 gobble(&alsoInvalid[0]); 37 38 // All of these should be fine. 39 gobbleref(Temporary()); 40 gobbleref(Temporary(10, 20)); 41 gobbleref(Temporary(10)); 42 gobbleref(10); 43 gobbleanyref(TemplateClass<int>()); 44 45 // All of these should error. 46 gobble(new Temporary); // expected-error {{variable of type 'Temporary' is only valid as a temporary}} expected-note {{value incorrectly allocated on the heap}} 47 gobble(new Temporary[10]); // expected-error {{variable of type 'Temporary' is only valid as a temporary}} expected-note {{value incorrectly allocated on the heap}} 48 gobble(new TemplateClass<int>); // expected-error {{variable of type 'TemplateClass<int>' is only valid as a temporary}} expected-note {{value incorrectly allocated on the heap}} 49 gobble(len <= 5 ? &invalid : new Temporary); // expected-error {{variable of type 'Temporary' is only valid as a temporary}} expected-note {{value incorrectly allocated on the heap}} 50 51 // Placement new is odd, but okay. 52 char buffer[sizeof(Temporary)]; 53 gobble(new (buffer) Temporary); 54 } 55 defaultArg(const Temporary & arg=Temporary ())56void defaultArg(const Temporary& arg = Temporary()) { // expected-error {{variable of type 'Temporary' is only valid as a temporary}} expected-note {{value incorrectly allocated in an automatic variable}} 57 } 58 59 // Can't be a global, this should error. 60 Temporary invalidStatic; // expected-error {{variable of type 'Temporary' is only valid as a temporary}} expected-note {{value incorrectly allocated in a global variable}} 61 62 struct RandomClass { 63 Temporary nonstaticMember; // This is okay if RandomClass is only used as a temporary. 64 static Temporary staticMember; // expected-error {{variable of type 'Temporary' is only valid as a temporary}} expected-note {{value incorrectly allocated in a global variable}} 65 }; 66 67 struct BadInherit : Temporary {}; 68 useStuffWrongly()69void useStuffWrongly() { 70 gobbleanyref(BadInherit()); 71 gobbleanyref(RandomClass()); 72 } 73