summaryrefslogtreecommitdiffstats
path: root/build/clang-plugin/tests/TestKungFuDeathGrip.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--build/clang-plugin/tests/TestKungFuDeathGrip.cpp142
1 files changed, 142 insertions, 0 deletions
diff --git a/build/clang-plugin/tests/TestKungFuDeathGrip.cpp b/build/clang-plugin/tests/TestKungFuDeathGrip.cpp
new file mode 100644
index 0000000000..0218015807
--- /dev/null
+++ b/build/clang-plugin/tests/TestKungFuDeathGrip.cpp
@@ -0,0 +1,142 @@
+#include <utility>
+
+#define MOZ_IMPLICIT __attribute__((annotate("moz_implicit")))
+
+template <typename T>
+class already_AddRefed {
+public:
+ already_AddRefed();
+ T* mPtr;
+};
+
+template <typename T>
+class RefPtr {
+public:
+ RefPtr();
+ MOZ_IMPLICIT RefPtr(T* aIn);
+ MOZ_IMPLICIT RefPtr(already_AddRefed<T> aIn);
+
+ RefPtr(const RefPtr<T>& aOther) = default;
+ RefPtr& operator=(const RefPtr<T>&) = default;
+
+ // We must define non-defaulted move operations as in the real RefPtr to make
+ // the type non-trivially-copyable.
+ RefPtr(RefPtr<T>&&);
+ RefPtr& operator=(RefPtr<T>&&);
+
+ void swap(RefPtr<T>& aOther);
+
+ ~RefPtr();
+ T* mPtr;
+};
+
+template <typename T>
+class nsCOMPtr {
+public:
+ nsCOMPtr();
+ MOZ_IMPLICIT nsCOMPtr(T* aIn);
+ MOZ_IMPLICIT nsCOMPtr(already_AddRefed<T> aIn);
+ ~nsCOMPtr();
+ T* mPtr;
+};
+
+class Type {
+public:
+ static nsCOMPtr<Type> someStaticCOMPtr;
+
+ void f(nsCOMPtr<Type> ignoredArgument, Type *param) {
+ nsCOMPtr<Type> never_referenced;
+ nsCOMPtr<Type> kfdg_t1(this);
+ nsCOMPtr<Type> kfdg_t2 = this;
+ nsCOMPtr<Type> kfdg_t3 = (this);
+
+ 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 pass 'kfdg_m1' to `mozilla::Unused`}}
+ 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 pass 'kfdg_m2' to `mozilla::Unused`}}
+ nsCOMPtr<Type> kfdg_m3(p);
+ kfdg_m3.mPtr->f(nullptr, nullptr);
+ nsCOMPtr<Type> kfdg_m4 = p;
+ kfdg_m4.mPtr->f(nullptr, nullptr);
+
+ nsCOMPtr<Type> kfdg_a1((already_AddRefed<Type>()));
+ nsCOMPtr<Type> kfdg_a2 = already_AddRefed<Type>();
+
+ nsCOMPtr<Type> kfdg_p1(param);
+ nsCOMPtr<Type> kfdg_p2 = param;
+
+
+ RefPtr<Type> never_referenced2;
+ RefPtr<Type> kfdg_t4(this);
+ RefPtr<Type> kfdg_t5 = this;
+ RefPtr<Type> kfdg_t6 = (this);
+
+ 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 pass 'kfdg_m5' to `mozilla::Unused`}}
+ 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 pass 'kfdg_m6' to `mozilla::Unused`}}
+ RefPtr<Type> kfdg_m7(p);
+ kfdg_m7.mPtr->f(nullptr, nullptr);
+ RefPtr<Type> kfdg_m8 = p;
+ kfdg_m8.mPtr->f(nullptr, nullptr);
+
+ RefPtr<Type> kfdg_a3((already_AddRefed<Type>()));
+ RefPtr<Type> kfdg_a4 = already_AddRefed<Type>();
+
+ RefPtr<Type> kfdg_p3(param);
+ RefPtr<Type> kfdg_p4 = param;
+ }
+
+ Type *p;
+};
+
+struct Type2 {
+ void f() {
+ mWeakRef->f(nullptr, nullptr);
+ }
+
+ void g() {
+ RefPtr<Type> kfdg;
+ kfdg.swap(mStrongRef);
+ f();
+ }
+
+ void h() {
+ RefPtr<Type> kfdg = std::move(mStrongRef);
+ f();
+ }
+
+ RefPtr<Type> mStrongRef;
+ Type* mWeakRef;
+};
+
+void f(nsCOMPtr<Type> ignoredArgument, Type *param) {
+ nsCOMPtr<Type> never_referenced;
+ Type t;
+ // Type *p = nullptr;
+ 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 pass 'kfdg_m1' to `mozilla::Unused`}}
+ 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 pass 'kfdg_m2' to `mozilla::Unused`}}
+ nsCOMPtr<Type> kfdg_m3(t.p);
+ kfdg_m3.mPtr->f(nullptr, nullptr);
+ nsCOMPtr<Type> kfdg_m4 = t.p;
+ kfdg_m4.mPtr->f(nullptr, nullptr);
+
+ nsCOMPtr<Type> kfdg_a1((already_AddRefed<Type>()));
+ nsCOMPtr<Type> kfdg_a2 = already_AddRefed<Type>();
+
+ nsCOMPtr<Type> kfdg_p1(param);
+ nsCOMPtr<Type> kfdg_p2 = param;
+
+
+ RefPtr<Type> never_referenced2;
+ 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 pass 'kfdg_m5' to `mozilla::Unused`}}
+ 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 pass 'kfdg_m6' to `mozilla::Unused`}}
+ RefPtr<Type> kfdg_m7(t.p);
+ kfdg_m7.mPtr->f(nullptr, nullptr);
+ RefPtr<Type> kfdg_m8 = t.p;
+ kfdg_m8.mPtr->f(nullptr, nullptr);
+
+ RefPtr<Type> kfdg_a3((already_AddRefed<Type>()));
+ RefPtr<Type> kfdg_a4 = already_AddRefed<Type>();
+
+ RefPtr<Type> kfdg_p3(param);
+ RefPtr<Type> kfdg_p4 = param;
+}
+
+nsCOMPtr<Type> Type::someStaticCOMPtr(nullptr);