TestNonTemporaryClass.cpp (3029B)
1 #define MOZ_NON_TEMPORARY_CLASS __attribute__((annotate("moz_non_temporary_class"))) 2 #define MOZ_IMPLICIT __attribute__((annotate("moz_implicit"))) 3 #define MOZ_RUNINIT __attribute__((annotate("moz_global_var"))) 4 5 #include <stddef.h> 6 7 struct MOZ_NON_TEMPORARY_CLASS NonTemporary { 8 int i = 0; 9 constexpr NonTemporary() {} 10 MOZ_IMPLICIT NonTemporary(int a) {} 11 NonTemporary(int a, int b) {} 12 void *operator new(size_t x) throw() { return 0; } 13 void *operator new(size_t blah, char *buffer) { return buffer; } 14 }; 15 16 template <class T> 17 struct MOZ_NON_TEMPORARY_CLASS TemplateClass { 18 T i; 19 }; 20 21 void gobble(void *) { } 22 23 void gobbleref(const NonTemporary&) { } 24 25 template <class T> 26 void gobbleanyref(const T&) { } 27 28 void misuseNonTemporaryClass(int len) { 29 NonTemporary invalid; 30 NonTemporary alsoInvalid[2]; 31 static NonTemporary invalidStatic; 32 static NonTemporary alsoInvalidStatic[2]; 33 34 gobble(&invalid); 35 gobble(&invalidStatic); 36 gobble(&alsoInvalid[0]); 37 38 gobbleref(NonTemporary()); // expected-error {{variable of type 'NonTemporary' is not valid in a temporary}} expected-note {{value incorrectly allocated in a temporary}} 39 gobbleref(NonTemporary(10, 20)); // expected-error {{variable of type 'NonTemporary' is not valid in a temporary}} expected-note {{value incorrectly allocated in a temporary}} 40 gobbleref(NonTemporary(10)); // expected-error {{variable of type 'NonTemporary' is not valid in a temporary}} expected-note {{value incorrectly allocated in a temporary}} 41 gobbleref(10); // expected-error {{variable of type 'NonTemporary' is not valid in a temporary}} expected-note {{value incorrectly allocated in a temporary}} 42 gobbleanyref(TemplateClass<int>()); // expected-error {{variable of type 'TemplateClass<int>' is not valid in a temporary}} expected-note {{value incorrectly allocated in a temporary}} 43 44 gobble(new NonTemporary); 45 gobble(new NonTemporary[10]); 46 gobble(new TemplateClass<int>); 47 gobble(len <= 5 ? &invalid : new NonTemporary); 48 49 char buffer[sizeof(NonTemporary)]; 50 gobble(new (buffer) NonTemporary); 51 } 52 53 void defaultArg(const NonTemporary& arg = NonTemporary()) { 54 } 55 56 NonTemporary invalidStatic; 57 struct RandomClass { 58 NonTemporary nonstaticMember; // expected-note {{'RandomClass' is a non-temporary type because member 'nonstaticMember' is a non-temporary type 'NonTemporary'}} 59 static NonTemporary staticMember; 60 }; 61 struct MOZ_NON_TEMPORARY_CLASS RandomNonTemporaryClass { 62 NonTemporary nonstaticMember; 63 static NonTemporary staticMember; 64 }; 65 66 struct BadInherit : NonTemporary {}; // expected-note {{'BadInherit' is a non-temporary type because it inherits from a non-temporary type 'NonTemporary'}} 67 68 void useStuffWrongly() { 69 gobbleanyref(BadInherit()); // expected-error {{variable of type 'BadInherit' is not valid in a temporary}} expected-note {{value incorrectly allocated in a temporary}} 70 gobbleanyref(RandomClass()); // expected-error {{variable of type 'RandomClass' is not valid in a temporary}} expected-note {{value incorrectly allocated in a temporary}} 71 }