Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(92)

Side by Side Diff: base/raw_scoped_refptr_mismatch_checker.h

Issue 3549010: Fix raw_scoped_refptr_mismatch_checker.h. (Closed) Base URL: http://src.chromium.org/git/chromium.git
Patch Set: Disable on Windows Created 10 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « base/callback.h ('k') | base/task.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef BASE_RAW_SCOPED_REFPTR_MISMATCH_CHECKER_H_ 5 #ifndef BASE_RAW_SCOPED_REFPTR_MISMATCH_CHECKER_H_
6 #define BASE_RAW_SCOPED_REFPTR_MISMATCH_CHECKER_H_ 6 #define BASE_RAW_SCOPED_REFPTR_MISMATCH_CHECKER_H_
7 #pragma once 7 #pragma once
8 8
9 #include "base/ref_counted.h" 9 #include "base/ref_counted.h"
10 #include "base/template_util.h"
10 #include "base/tuple.h" 11 #include "base/tuple.h"
12 #include "build/build_config.h"
11 13
12 // It is dangerous to post a task with a raw pointer argument to a function 14 // It is dangerous to post a task with a T* argument where T is a subtype of
13 // that expects a scoped_refptr<>. The compiler will happily accept the 15 // RefCounted(Base|ThreadSafeBase), since by the time the parameter is used, the
14 // situation, but it will not attempt to increase the refcount until the task 16 // object may already have been deleted since it was not held with a
15 // runs. Callers expecting the argument to be refcounted up at post time are 17 // scoped_refptr. Example: http://crbug.com/27191
16 // in for a nasty surprise! Example: http://crbug.com/27191
17 // The following set of traits are designed to generate a compile error 18 // The following set of traits are designed to generate a compile error
18 // whenever this antipattern is attempted. 19 // whenever this antipattern is attempted.
19 template <class A, class B> 20
20 struct ExpectsScopedRefptrButGetsRawPtr { 21 namespace base {
22
23 // This is a base internal implementation file used by task.h and callback.h.
24 // Not for public consumption, so we wrap it in namespace internal.
25 namespace internal {
26
27 template <typename T>
28 struct NeedsScopedRefptrButGetsRawPtr {
29 #if defined(OS_WIN)
30 enum {
31 value = base::false_type::value
32 };
33 #else
34 enum {
35 // Human readable translation: you needed to be a scoped_refptr if you are a
36 // raw pointer type and are convertible to a RefCounted(Base|ThreadSafeBase)
37 // type.
38 value = (is_pointer<T>::value &&
39 (is_convertible<T, subtle::RefCountedBase*>::value ||
40 is_convertible<T, subtle::RefCountedThreadSafeBase*>::value))
41 };
42 #endif
43 };
44
45 template <typename Params>
46 struct ParamsUseScopedRefptrCorrectly {
21 enum { value = 0 }; 47 enum { value = 0 };
22 }; 48 };
23 49
24 template <class A, class B> 50 template <>
25 struct ExpectsScopedRefptrButGetsRawPtr<scoped_refptr<A>, B*> { 51 struct ParamsUseScopedRefptrCorrectly<Tuple0> {
26 enum { value = 1 }; 52 enum { value = 1 };
27 }; 53 };
28 54
29 template <class Function, class Params> 55 template <typename A>
30 struct FunctionUsesScopedRefptrCorrectly { 56 struct ParamsUseScopedRefptrCorrectly<Tuple1<A> > {
31 enum { value = 1 }; 57 enum { value = !NeedsScopedRefptrButGetsRawPtr<A>::value };
32 }; 58 };
33 59
34 template <class A1, class A2> 60 template <typename A, typename B>
35 struct FunctionUsesScopedRefptrCorrectly<void (*)(A1), Tuple1<A2> > { 61 struct ParamsUseScopedRefptrCorrectly<Tuple2<A, B> > {
36 enum { value = !ExpectsScopedRefptrButGetsRawPtr<A1, A2>::value }; 62 enum { value = !(NeedsScopedRefptrButGetsRawPtr<A>::value ||
63 NeedsScopedRefptrButGetsRawPtr<B>::value) };
37 }; 64 };
38 65
39 template <class A1, class B1, class A2, class B2> 66 template <typename A, typename B, typename C>
40 struct FunctionUsesScopedRefptrCorrectly<void (*)(A1, B1), Tuple2<A2, B2> > { 67 struct ParamsUseScopedRefptrCorrectly<Tuple3<A, B, C> > {
41 enum { value = !(ExpectsScopedRefptrButGetsRawPtr<A1, A2>::value || 68 enum { value = !(NeedsScopedRefptrButGetsRawPtr<A>::value ||
42 ExpectsScopedRefptrButGetsRawPtr<B1, B2>::value) }; 69 NeedsScopedRefptrButGetsRawPtr<B>::value ||
70 NeedsScopedRefptrButGetsRawPtr<C>::value) };
43 }; 71 };
44 72
45 template <class A1, class B1, class C1, class A2, class B2, class C2> 73 template <typename A, typename B, typename C, typename D>
46 struct FunctionUsesScopedRefptrCorrectly<void (*)(A1, B1, C1), 74 struct ParamsUseScopedRefptrCorrectly<Tuple4<A, B, C, D> > {
47 Tuple3<A2, B2, C2> > { 75 enum { value = !(NeedsScopedRefptrButGetsRawPtr<A>::value ||
48 enum { value = !(ExpectsScopedRefptrButGetsRawPtr<A1, A2>::value || 76 NeedsScopedRefptrButGetsRawPtr<B>::value ||
49 ExpectsScopedRefptrButGetsRawPtr<B1, B2>::value || 77 NeedsScopedRefptrButGetsRawPtr<C>::value ||
50 ExpectsScopedRefptrButGetsRawPtr<C1, C2>::value) }; 78 NeedsScopedRefptrButGetsRawPtr<D>::value) };
51 }; 79 };
52 80
53 template <class A1, class B1, class C1, class D1, 81 template <typename A, typename B, typename C, typename D, typename E>
54 class A2, class B2, class C2, class D2> 82 struct ParamsUseScopedRefptrCorrectly<Tuple5<A, B, C, D, E> > {
55 struct FunctionUsesScopedRefptrCorrectly<void (*)(A1, B1, C1, D1), 83 enum { value = !(NeedsScopedRefptrButGetsRawPtr<A>::value ||
56 Tuple4<A2, B2, C2, D2> > { 84 NeedsScopedRefptrButGetsRawPtr<B>::value ||
57 enum { value = !(ExpectsScopedRefptrButGetsRawPtr<A1, A2>::value || 85 NeedsScopedRefptrButGetsRawPtr<C>::value ||
58 ExpectsScopedRefptrButGetsRawPtr<B1, B2>::value || 86 NeedsScopedRefptrButGetsRawPtr<D>::value ||
59 ExpectsScopedRefptrButGetsRawPtr<C1, C2>::value || 87 NeedsScopedRefptrButGetsRawPtr<E>::value) };
60 ExpectsScopedRefptrButGetsRawPtr<D1, D2>::value) };
61 }; 88 };
62 89
63 template <class A1, class B1, class C1, class D1, class E1, 90 template <typename A, typename B, typename C, typename D, typename E,
64 class A2, class B2, class C2, class D2, class E2> 91 typename F>
65 struct FunctionUsesScopedRefptrCorrectly<void (*)(A1, B1, C1, D1, E1), 92 struct ParamsUseScopedRefptrCorrectly<Tuple6<A, B, C, D, E, F> > {
66 Tuple5<A2, B2, C2, D2, E2> > { 93 enum { value = !(NeedsScopedRefptrButGetsRawPtr<A>::value ||
67 enum { value = !(ExpectsScopedRefptrButGetsRawPtr<A1, A2>::value || 94 NeedsScopedRefptrButGetsRawPtr<B>::value ||
68 ExpectsScopedRefptrButGetsRawPtr<B1, B2>::value || 95 NeedsScopedRefptrButGetsRawPtr<C>::value ||
69 ExpectsScopedRefptrButGetsRawPtr<C1, C2>::value || 96 NeedsScopedRefptrButGetsRawPtr<D>::value ||
70 ExpectsScopedRefptrButGetsRawPtr<D1, D2>::value || 97 NeedsScopedRefptrButGetsRawPtr<E>::value ||
71 ExpectsScopedRefptrButGetsRawPtr<E1, E2>::value) }; 98 NeedsScopedRefptrButGetsRawPtr<F>::value) };
72 }; 99 };
73 100
74 template <class A1, class B1, class C1, class D1, class E1, class F1, 101 template <typename A, typename B, typename C, typename D, typename E,
75 class A2, class B2, class C2, class D2, class E2, class F2> 102 typename F, typename G>
76 struct FunctionUsesScopedRefptrCorrectly<void (*)(A1, B1, C1, D1, E1, F1), 103 struct ParamsUseScopedRefptrCorrectly<Tuple7<A, B, C, D, E, F, G> > {
77 Tuple6<A2, B2, C2, D2, E2, F2> > { 104 enum { value = !(NeedsScopedRefptrButGetsRawPtr<A>::value ||
78 enum { value = !(ExpectsScopedRefptrButGetsRawPtr<A1, A2>::value || 105 NeedsScopedRefptrButGetsRawPtr<B>::value ||
79 ExpectsScopedRefptrButGetsRawPtr<B1, B2>::value || 106 NeedsScopedRefptrButGetsRawPtr<C>::value ||
80 ExpectsScopedRefptrButGetsRawPtr<C1, C2>::value || 107 NeedsScopedRefptrButGetsRawPtr<D>::value ||
81 ExpectsScopedRefptrButGetsRawPtr<D1, D2>::value || 108 NeedsScopedRefptrButGetsRawPtr<E>::value ||
82 ExpectsScopedRefptrButGetsRawPtr<E1, E2>::value || 109 NeedsScopedRefptrButGetsRawPtr<F>::value ||
83 ExpectsScopedRefptrButGetsRawPtr<F1, F2>::value) }; 110 NeedsScopedRefptrButGetsRawPtr<G>::value) };
84 }; 111 };
85 112
86 template <class A1, class B1, class C1, class D1, class E1, class F1, class G1, 113 template <typename A, typename B, typename C, typename D, typename E,
87 class A2, class B2, class C2, class D2, class E2, class F2, class G2> 114 typename F, typename G, typename H>
88 struct FunctionUsesScopedRefptrCorrectly<void (*)(A1, B1, C1, D1, E1, F1, G1), 115 struct ParamsUseScopedRefptrCorrectly<Tuple8<A, B, C, D, E, F, G, H> > {
89 Tuple7<A2, B2, C2, D2, E2, F2, G2> > { 116 enum { value = !(NeedsScopedRefptrButGetsRawPtr<A>::value ||
90 enum { value = !(ExpectsScopedRefptrButGetsRawPtr<A1, A2>::value || 117 NeedsScopedRefptrButGetsRawPtr<B>::value ||
91 ExpectsScopedRefptrButGetsRawPtr<B1, B2>::value || 118 NeedsScopedRefptrButGetsRawPtr<C>::value ||
92 ExpectsScopedRefptrButGetsRawPtr<C1, C2>::value || 119 NeedsScopedRefptrButGetsRawPtr<D>::value ||
93 ExpectsScopedRefptrButGetsRawPtr<D1, D2>::value || 120 NeedsScopedRefptrButGetsRawPtr<E>::value ||
94 ExpectsScopedRefptrButGetsRawPtr<E1, E2>::value || 121 NeedsScopedRefptrButGetsRawPtr<F>::value ||
95 ExpectsScopedRefptrButGetsRawPtr<F1, F2>::value || 122 NeedsScopedRefptrButGetsRawPtr<G>::value ||
96 ExpectsScopedRefptrButGetsRawPtr<G1, G2>::value) }; 123 NeedsScopedRefptrButGetsRawPtr<H>::value) };
97 }; 124 };
98 125
99 template <class Method, class Params> 126 } // namespace internal
100 struct MethodUsesScopedRefptrCorrectly {
101 enum { value = 1 };
102 };
103 127
104 template <class T, class A1, class A2> 128 } // namespace base
105 struct MethodUsesScopedRefptrCorrectly<void (T::*)(A1), Tuple1<A2> > {
106 enum { value = !ExpectsScopedRefptrButGetsRawPtr<A1, A2>::value };
107 };
108
109 template <class T, class A1, class B1, class A2, class B2>
110 struct MethodUsesScopedRefptrCorrectly<void (T::*)(A1, B1), Tuple2<A2, B2> > {
111 enum { value = !(ExpectsScopedRefptrButGetsRawPtr<A1, A2>::value ||
112 ExpectsScopedRefptrButGetsRawPtr<B1, B2>::value) };
113 };
114
115 template <class T, class A1, class B1, class C1,
116 class A2, class B2, class C2>
117 struct MethodUsesScopedRefptrCorrectly<void (T::*)(A1, B1, C1),
118 Tuple3<A2, B2, C2> > {
119 enum { value = !(ExpectsScopedRefptrButGetsRawPtr<A1, A2>::value ||
120 ExpectsScopedRefptrButGetsRawPtr<B1, B2>::value ||
121 ExpectsScopedRefptrButGetsRawPtr<C1, C2>::value) };
122 };
123
124 template <class T, class A1, class B1, class C1, class D1,
125 class A2, class B2, class C2, class D2>
126 struct MethodUsesScopedRefptrCorrectly<void (T::*)(A1, B1, C1, D1),
127 Tuple4<A2, B2, C2, D2> > {
128 enum { value = !(ExpectsScopedRefptrButGetsRawPtr<A1, A2>::value ||
129 ExpectsScopedRefptrButGetsRawPtr<B1, B2>::value ||
130 ExpectsScopedRefptrButGetsRawPtr<C1, C2>::value ||
131 ExpectsScopedRefptrButGetsRawPtr<D1, D2>::value) };
132 };
133
134 template <class T, class A1, class B1, class C1, class D1, class E1,
135 class A2, class B2, class C2, class D2, class E2>
136 struct MethodUsesScopedRefptrCorrectly<void (T::*)(A1, B1, C1, D1, E1),
137 Tuple5<A2, B2, C2, D2, E2> > {
138 enum { value = !(ExpectsScopedRefptrButGetsRawPtr<A1, A2>::value ||
139 ExpectsScopedRefptrButGetsRawPtr<B1, B2>::value ||
140 ExpectsScopedRefptrButGetsRawPtr<C1, C2>::value ||
141 ExpectsScopedRefptrButGetsRawPtr<D1, D2>::value ||
142 ExpectsScopedRefptrButGetsRawPtr<E1, E2>::value) };
143 };
144
145 template <class T, class A1, class B1, class C1, class D1, class E1, class F1,
146 class A2, class B2, class C2, class D2, class E2, class F2>
147 struct MethodUsesScopedRefptrCorrectly<void (T::*)(A1, B1, C1, D1, E1, F1),
148 Tuple6<A2, B2, C2, D2, E2, F2> > {
149 enum { value = !(ExpectsScopedRefptrButGetsRawPtr<A1, A2>::value ||
150 ExpectsScopedRefptrButGetsRawPtr<B1, B2>::value ||
151 ExpectsScopedRefptrButGetsRawPtr<C1, C2>::value ||
152 ExpectsScopedRefptrButGetsRawPtr<D1, D2>::value ||
153 ExpectsScopedRefptrButGetsRawPtr<E1, E2>::value ||
154 ExpectsScopedRefptrButGetsRawPtr<F1, F2>::value) };
155 };
156
157 template <class T,
158 class A1, class B1, class C1, class D1, class E1, class F1, class G1,
159 class A2, class B2, class C2, class D2, class E2, class F2, class G2>
160 struct MethodUsesScopedRefptrCorrectly<void (T::*)(A1, B1, C1, D1, E1, F1, G1),
161 Tuple7<A2, B2, C2, D2, E2, F2, G2> > {
162 enum { value = !(ExpectsScopedRefptrButGetsRawPtr<A1, A2>::value ||
163 ExpectsScopedRefptrButGetsRawPtr<B1, B2>::value ||
164 ExpectsScopedRefptrButGetsRawPtr<C1, C2>::value ||
165 ExpectsScopedRefptrButGetsRawPtr<D1, D2>::value ||
166 ExpectsScopedRefptrButGetsRawPtr<E1, E2>::value ||
167 ExpectsScopedRefptrButGetsRawPtr<F1, F2>::value ||
168 ExpectsScopedRefptrButGetsRawPtr<G1, G2>::value) };
169 };
170 129
171 #endif // BASE_RAW_SCOPED_REFPTR_MISMATCH_CHECKER_H_ 130 #endif // BASE_RAW_SCOPED_REFPTR_MISMATCH_CHECKER_H_
OLDNEW
« no previous file with comments | « base/callback.h ('k') | base/task.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698