TestKungFuDeathGrip.cpp (5190B)
1 #include <utility> 2 3 #define MOZ_IMPLICIT __attribute__((annotate("moz_implicit"))) 4 #define MOZ_RUNINIT __attribute__((annotate("moz_global_var"))) 5 6 template <typename T> 7 class already_AddRefed { 8 public: 9 already_AddRefed(); 10 T* mPtr; 11 }; 12 13 template <typename T> 14 class RefPtr { 15 public: 16 RefPtr(); 17 MOZ_IMPLICIT RefPtr(T* aIn); 18 MOZ_IMPLICIT RefPtr(already_AddRefed<T> aIn); 19 20 RefPtr(const RefPtr<T>& aOther) = default; 21 RefPtr& operator=(const RefPtr<T>&) = default; 22 23 // We must define non-defaulted move operations as in the real RefPtr to make 24 // the type non-trivially-copyable. 25 RefPtr(RefPtr<T>&&); 26 RefPtr& operator=(RefPtr<T>&&); 27 28 void swap(RefPtr<T>& aOther); 29 30 ~RefPtr(); 31 T* mPtr; 32 }; 33 34 template <typename T> 35 class nsCOMPtr { 36 public: 37 nsCOMPtr(); 38 MOZ_IMPLICIT nsCOMPtr(T* aIn); 39 MOZ_IMPLICIT nsCOMPtr(already_AddRefed<T> aIn); 40 ~nsCOMPtr(); 41 T* mPtr; 42 }; 43 44 class Type { 45 public: 46 static nsCOMPtr<Type> someStaticCOMPtr; 47 48 void f(nsCOMPtr<Type> ignoredArgument, Type *param) { 49 nsCOMPtr<Type> never_referenced; 50 nsCOMPtr<Type> kfdg_t1(this); 51 nsCOMPtr<Type> kfdg_t2 = this; 52 nsCOMPtr<Type> kfdg_t3 = (this); 53 54 nsCOMPtr<Type> kfdg_m1(p); // expected-error {{Unused "kungFuDeathGrip" 'nsCOMPtr<Type>' objects constructed from members are prohibited}} expected-note {{Please switch all accesses to this member to go through 'kfdg_m1', or explicitly cast 'kfdg_m1' to `(void)`}} 55 nsCOMPtr<Type> kfdg_m2 = p; // expected-error {{Unused "kungFuDeathGrip" 'nsCOMPtr<Type>' objects constructed from members are prohibited}} expected-note {{Please switch all accesses to this member to go through 'kfdg_m2', or explicitly cast 'kfdg_m2' to `(void)`}} 56 nsCOMPtr<Type> kfdg_m3(p); 57 kfdg_m3.mPtr->f(nullptr, nullptr); 58 nsCOMPtr<Type> kfdg_m4 = p; 59 kfdg_m4.mPtr->f(nullptr, nullptr); 60 61 nsCOMPtr<Type> kfdg_a1((already_AddRefed<Type>())); 62 nsCOMPtr<Type> kfdg_a2 = already_AddRefed<Type>(); 63 64 nsCOMPtr<Type> kfdg_p1(param); 65 nsCOMPtr<Type> kfdg_p2 = param; 66 67 68 RefPtr<Type> never_referenced2; 69 RefPtr<Type> kfdg_t4(this); 70 RefPtr<Type> kfdg_t5 = this; 71 RefPtr<Type> kfdg_t6 = (this); 72 73 RefPtr<Type> kfdg_m5(p); // expected-error {{Unused "kungFuDeathGrip" 'RefPtr<Type>' objects constructed from members are prohibited}} expected-note {{Please switch all accesses to this member to go through 'kfdg_m5', or explicitly cast 'kfdg_m5' to `(void)`}} 74 RefPtr<Type> kfdg_m6 = p; // expected-error {{Unused "kungFuDeathGrip" 'RefPtr<Type>' objects constructed from members are prohibited}} expected-note {{Please switch all accesses to this member to go through 'kfdg_m6', or explicitly cast 'kfdg_m6' to `(void)`}} 75 RefPtr<Type> kfdg_m7(p); 76 kfdg_m7.mPtr->f(nullptr, nullptr); 77 RefPtr<Type> kfdg_m8 = p; 78 kfdg_m8.mPtr->f(nullptr, nullptr); 79 80 RefPtr<Type> kfdg_a3((already_AddRefed<Type>())); 81 RefPtr<Type> kfdg_a4 = already_AddRefed<Type>(); 82 83 RefPtr<Type> kfdg_p3(param); 84 RefPtr<Type> kfdg_p4 = param; 85 } 86 87 Type *p; 88 }; 89 90 struct Type2 { 91 void f() { 92 mWeakRef->f(nullptr, nullptr); 93 } 94 95 void g() { 96 RefPtr<Type> kfdg; 97 kfdg.swap(mStrongRef); 98 f(); 99 } 100 101 void h() { 102 RefPtr<Type> kfdg = std::move(mStrongRef); 103 f(); 104 } 105 106 RefPtr<Type> mStrongRef; 107 Type* mWeakRef; 108 }; 109 110 void f(nsCOMPtr<Type> ignoredArgument, Type *param) { 111 nsCOMPtr<Type> never_referenced; 112 Type t; 113 // Type *p = nullptr; 114 nsCOMPtr<Type> kfdg_m1(t.p); // expected-error {{Unused "kungFuDeathGrip" 'nsCOMPtr<Type>' objects constructed from members are prohibited}} expected-note {{Please switch all accesses to this member to go through 'kfdg_m1', or explicitly cast 'kfdg_m1' to `(void)`}} 115 nsCOMPtr<Type> kfdg_m2 = t.p; // expected-error {{Unused "kungFuDeathGrip" 'nsCOMPtr<Type>' objects constructed from members are prohibited}} expected-note {{Please switch all accesses to this member to go through 'kfdg_m2', or explicitly cast 'kfdg_m2' to `(void)`}} 116 nsCOMPtr<Type> kfdg_m3(t.p); 117 kfdg_m3.mPtr->f(nullptr, nullptr); 118 nsCOMPtr<Type> kfdg_m4 = t.p; 119 kfdg_m4.mPtr->f(nullptr, nullptr); 120 121 nsCOMPtr<Type> kfdg_a1((already_AddRefed<Type>())); 122 nsCOMPtr<Type> kfdg_a2 = already_AddRefed<Type>(); 123 124 nsCOMPtr<Type> kfdg_p1(param); 125 nsCOMPtr<Type> kfdg_p2 = param; 126 127 128 RefPtr<Type> never_referenced2; 129 RefPtr<Type> kfdg_m5(t.p); // expected-error {{Unused "kungFuDeathGrip" 'RefPtr<Type>' objects constructed from members are prohibited}} expected-note {{Please switch all accesses to this member to go through 'kfdg_m5', or explicitly cast 'kfdg_m5' to `(void)`}} 130 RefPtr<Type> kfdg_m6 = t.p; // expected-error {{Unused "kungFuDeathGrip" 'RefPtr<Type>' objects constructed from members are prohibited}} expected-note {{Please switch all accesses to this member to go through 'kfdg_m6', or explicitly cast 'kfdg_m6' to `(void)`}} 131 RefPtr<Type> kfdg_m7(t.p); 132 kfdg_m7.mPtr->f(nullptr, nullptr); 133 RefPtr<Type> kfdg_m8 = t.p; 134 kfdg_m8.mPtr->f(nullptr, nullptr); 135 136 RefPtr<Type> kfdg_a3((already_AddRefed<Type>())); 137 RefPtr<Type> kfdg_a4 = already_AddRefed<Type>(); 138 139 RefPtr<Type> kfdg_p3(param); 140 RefPtr<Type> kfdg_p4 = param; 141 } 142 143 MOZ_RUNINIT nsCOMPtr<Type> Type::someStaticCOMPtr(nullptr);