summaryrefslogtreecommitdiffstats
path: root/base/raw_scoped_refptr_mismatch_checker.h
diff options
context:
space:
mode:
authorjamesr@chromium.org <jamesr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-12-02 01:44:30 +0000
committerjamesr@chromium.org <jamesr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-12-02 01:44:30 +0000
commit7c87290fed96e7620b3702bc9435db6bc957d92c (patch)
tree43b6be5e45147a6ebc641012da2444446e6f74f3 /base/raw_scoped_refptr_mismatch_checker.h
parent4559a7d9c3eca928fc19b64b64f19c8032d0ee0f (diff)
downloadchromium_src-7c87290fed96e7620b3702bc9435db6bc957d92c.zip
chromium_src-7c87290fed96e7620b3702bc9435db6bc957d92c.tar.gz
chromium_src-7c87290fed96e7620b3702bc9435db6bc957d92c.tar.bz2
Tries to catch callbacks expecting scoped_refptr<T> and getting T* using template magic
Review URL: http://codereview.chromium.org/414024 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@33531 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base/raw_scoped_refptr_mismatch_checker.h')
-rw-r--r--base/raw_scoped_refptr_mismatch_checker.h170
1 files changed, 170 insertions, 0 deletions
diff --git a/base/raw_scoped_refptr_mismatch_checker.h b/base/raw_scoped_refptr_mismatch_checker.h
new file mode 100644
index 0000000..598710f
--- /dev/null
+++ b/base/raw_scoped_refptr_mismatch_checker.h
@@ -0,0 +1,170 @@
+// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef BASE_RAW_SCOPED_REFPTR_MISMATCH_CHECKER_H_
+#define BASE_RAW_SCOPED_REFPTR_MISMATCH_CHECKER_H_
+
+#include "base/ref_counted.h"
+#include "base/tuple.h"
+
+// It is dangerous to post a task with a raw pointer argument to a function
+// that expects a scoped_refptr<>. The compiler will happily accept the
+// situation, but it will not attempt to increase the refcount until the task
+// runs. Callers expecting the argument to be refcounted up at post time are
+// in for a nasty surprise! Example: http://crbug.com/27191
+// The following set of traits are designed to generate a compile error
+// whenever this antipattern is attempted.
+template <class A, class B>
+struct ExpectsScopedRefptrButGetsRawPtr {
+ enum { value = 0 };
+};
+
+template <class A, class B>
+struct ExpectsScopedRefptrButGetsRawPtr<scoped_refptr<A>, B*> {
+ enum { value = 1 };
+};
+
+template <class Function, class Params>
+struct FunctionUsesScopedRefptrCorrectly {
+ enum { value = 1 };
+};
+
+template <class A1, class A2>
+struct FunctionUsesScopedRefptrCorrectly<void (*)(A1), Tuple1<A2> > {
+ enum { value = !ExpectsScopedRefptrButGetsRawPtr<A1, A2>::value };
+};
+
+template <class A1, class B1, class A2, class B2>
+struct FunctionUsesScopedRefptrCorrectly<void (*)(A1, B1), Tuple2<A2, B2> > {
+ enum { value = !(ExpectsScopedRefptrButGetsRawPtr<A1, A2>::value ||
+ ExpectsScopedRefptrButGetsRawPtr<B1, B2>::value) };
+};
+
+template <class A1, class B1, class C1, class A2, class B2, class C2>
+struct FunctionUsesScopedRefptrCorrectly<void (*)(A1, B1, C1),
+ Tuple3<A2, B2, C2> > {
+ enum { value = !(ExpectsScopedRefptrButGetsRawPtr<A1, A2>::value ||
+ ExpectsScopedRefptrButGetsRawPtr<B1, B2>::value ||
+ ExpectsScopedRefptrButGetsRawPtr<C1, C2>::value) };
+};
+
+template <class A1, class B1, class C1, class D1,
+ class A2, class B2, class C2, class D2>
+struct FunctionUsesScopedRefptrCorrectly<void (*)(A1, B1, C1, D1),
+ Tuple4<A2, B2, C2, D2> > {
+ enum { value = !(ExpectsScopedRefptrButGetsRawPtr<A1, A2>::value ||
+ ExpectsScopedRefptrButGetsRawPtr<B1, B2>::value ||
+ ExpectsScopedRefptrButGetsRawPtr<C1, C2>::value ||
+ ExpectsScopedRefptrButGetsRawPtr<D1, D2>::value) };
+};
+
+template <class A1, class B1, class C1, class D1, class E1,
+ class A2, class B2, class C2, class D2, class E2>
+struct FunctionUsesScopedRefptrCorrectly<void (*)(A1, B1, C1, D1, E1),
+ Tuple5<A2, B2, C2, D2, E2> > {
+ enum { value = !(ExpectsScopedRefptrButGetsRawPtr<A1, A2>::value ||
+ ExpectsScopedRefptrButGetsRawPtr<B1, B2>::value ||
+ ExpectsScopedRefptrButGetsRawPtr<C1, C2>::value ||
+ ExpectsScopedRefptrButGetsRawPtr<D1, D2>::value ||
+ ExpectsScopedRefptrButGetsRawPtr<E1, E2>::value) };
+};
+
+template <class A1, class B1, class C1, class D1, class E1, class F1,
+ class A2, class B2, class C2, class D2, class E2, class F2>
+struct FunctionUsesScopedRefptrCorrectly<void (*)(A1, B1, C1, D1, E1, F1),
+ Tuple6<A2, B2, C2, D2, E2, F2> > {
+ enum { value = !(ExpectsScopedRefptrButGetsRawPtr<A1, A2>::value ||
+ ExpectsScopedRefptrButGetsRawPtr<B1, B2>::value ||
+ ExpectsScopedRefptrButGetsRawPtr<C1, C2>::value ||
+ ExpectsScopedRefptrButGetsRawPtr<D1, D2>::value ||
+ ExpectsScopedRefptrButGetsRawPtr<E1, E2>::value ||
+ ExpectsScopedRefptrButGetsRawPtr<F1, F2>::value) };
+};
+
+template <class A1, class B1, class C1, class D1, class E1, class F1, class G1,
+ class A2, class B2, class C2, class D2, class E2, class F2, class G2>
+struct FunctionUsesScopedRefptrCorrectly<void (*)(A1, B1, C1, D1, E1, F1, G1),
+ Tuple7<A2, B2, C2, D2, E2, F2, G2> > {
+ enum { value = !(ExpectsScopedRefptrButGetsRawPtr<A1, A2>::value ||
+ ExpectsScopedRefptrButGetsRawPtr<B1, B2>::value ||
+ ExpectsScopedRefptrButGetsRawPtr<C1, C2>::value ||
+ ExpectsScopedRefptrButGetsRawPtr<D1, D2>::value ||
+ ExpectsScopedRefptrButGetsRawPtr<E1, E2>::value ||
+ ExpectsScopedRefptrButGetsRawPtr<F1, F2>::value ||
+ ExpectsScopedRefptrButGetsRawPtr<G1, G2>::value) };
+};
+
+template <class Method, class Params>
+struct MethodUsesScopedRefptrCorrectly {
+ enum { value = 1 };
+};
+
+template <class T, class A1, class A2>
+struct MethodUsesScopedRefptrCorrectly<void (T::*)(A1), Tuple1<A2> > {
+ enum { value = !ExpectsScopedRefptrButGetsRawPtr<A1, A2>::value };
+};
+
+template <class T, class A1, class B1, class A2, class B2>
+struct MethodUsesScopedRefptrCorrectly<void (T::*)(A1, B1), Tuple2<A2, B2> > {
+ enum { value = !(ExpectsScopedRefptrButGetsRawPtr<A1, A2>::value ||
+ ExpectsScopedRefptrButGetsRawPtr<B1, B2>::value) };
+};
+
+template <class T, class A1, class B1, class C1,
+ class A2, class B2, class C2>
+struct MethodUsesScopedRefptrCorrectly<void (T::*)(A1, B1, C1),
+ Tuple3<A2, B2, C2> > {
+ enum { value = !(ExpectsScopedRefptrButGetsRawPtr<A1, A2>::value ||
+ ExpectsScopedRefptrButGetsRawPtr<B1, B2>::value ||
+ ExpectsScopedRefptrButGetsRawPtr<C1, C2>::value) };
+};
+
+template <class T, class A1, class B1, class C1, class D1,
+ class A2, class B2, class C2, class D2>
+struct MethodUsesScopedRefptrCorrectly<void (T::*)(A1, B1, C1, D1),
+ Tuple4<A2, B2, C2, D2> > {
+ enum { value = !(ExpectsScopedRefptrButGetsRawPtr<A1, A2>::value ||
+ ExpectsScopedRefptrButGetsRawPtr<B1, B2>::value ||
+ ExpectsScopedRefptrButGetsRawPtr<C1, C2>::value ||
+ ExpectsScopedRefptrButGetsRawPtr<D1, D2>::value) };
+};
+
+template <class T, class A1, class B1, class C1, class D1, class E1,
+ class A2, class B2, class C2, class D2, class E2>
+struct MethodUsesScopedRefptrCorrectly<void (T::*)(A1, B1, C1, D1, E1),
+ Tuple5<A2, B2, C2, D2, E2> > {
+ enum { value = !(ExpectsScopedRefptrButGetsRawPtr<A1, A2>::value ||
+ ExpectsScopedRefptrButGetsRawPtr<B1, B2>::value ||
+ ExpectsScopedRefptrButGetsRawPtr<C1, C2>::value ||
+ ExpectsScopedRefptrButGetsRawPtr<D1, D2>::value ||
+ ExpectsScopedRefptrButGetsRawPtr<E1, E2>::value) };
+};
+
+template <class T, class A1, class B1, class C1, class D1, class E1, class F1,
+ class A2, class B2, class C2, class D2, class E2, class F2>
+struct MethodUsesScopedRefptrCorrectly<void (T::*)(A1, B1, C1, D1, E1, F1),
+ Tuple6<A2, B2, C2, D2, E2, F2> > {
+ enum { value = !(ExpectsScopedRefptrButGetsRawPtr<A1, A2>::value ||
+ ExpectsScopedRefptrButGetsRawPtr<B1, B2>::value ||
+ ExpectsScopedRefptrButGetsRawPtr<C1, C2>::value ||
+ ExpectsScopedRefptrButGetsRawPtr<D1, D2>::value ||
+ ExpectsScopedRefptrButGetsRawPtr<E1, E2>::value ||
+ ExpectsScopedRefptrButGetsRawPtr<F1, F2>::value) };
+};
+
+template <class T,
+ class A1, class B1, class C1, class D1, class E1, class F1, class G1,
+ class A2, class B2, class C2, class D2, class E2, class F2, class G2>
+struct MethodUsesScopedRefptrCorrectly<void (T::*)(A1, B1, C1, D1, E1, F1, G1),
+ Tuple7<A2, B2, C2, D2, E2, F2, G2> > {
+ enum { value = !(ExpectsScopedRefptrButGetsRawPtr<A1, A2>::value ||
+ ExpectsScopedRefptrButGetsRawPtr<B1, B2>::value ||
+ ExpectsScopedRefptrButGetsRawPtr<C1, C2>::value ||
+ ExpectsScopedRefptrButGetsRawPtr<D1, D2>::value ||
+ ExpectsScopedRefptrButGetsRawPtr<E1, E2>::value ||
+ ExpectsScopedRefptrButGetsRawPtr<F1, F2>::value ||
+ ExpectsScopedRefptrButGetsRawPtr<G1, G2>::value) };
+};
+
+#endif // BASE_RAW_SCOPED_REFPTR_MISMATCH_CHECKER_H_