1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef BASE_MEMORY_RAW_SCOPED_REFPTR_MISMATCH_CHECKER_H_
6 #define BASE_MEMORY_RAW_SCOPED_REFPTR_MISMATCH_CHECKER_H_
8 #include "base/memory/ref_counted.h"
9 #include "base/template_util.h"
10 #include "base/tuple.h"
11 #include "build/build_config.h"
13 // It is dangerous to post a task with a T* argument where T is a subtype of
14 // RefCounted(Base|ThreadSafeBase), since by the time the parameter is used, the
15 // object may already have been deleted since it was not held with a
16 // scoped_refptr. Example: http://crbug.com/27191
17 // The following set of traits are designed to generate a compile error
18 // whenever this antipattern is attempted.
22 // This is a base internal implementation file used by task.h and callback.h.
23 // Not for public consumption, so we wrap it in namespace internal.
27 struct NeedsScopedRefptrButGetsRawPtr
{
30 value
= base::false_type::value
34 // Human readable translation: you needed to be a scoped_refptr if you are a
35 // raw pointer type and are convertible to a RefCounted(Base|ThreadSafeBase)
37 value
= (is_pointer
<T
>::value
&&
38 (is_convertible
<T
, subtle::RefCountedBase
*>::value
||
39 is_convertible
<T
, subtle::RefCountedThreadSafeBase
*>::value
))
44 template <typename Params
>
45 struct ParamsUseScopedRefptrCorrectly
{
50 struct ParamsUseScopedRefptrCorrectly
<Tuple
<>> {
55 struct ParamsUseScopedRefptrCorrectly
<Tuple
<A
>> {
56 enum { value
= !NeedsScopedRefptrButGetsRawPtr
<A
>::value
};
59 template <typename A
, typename B
>
60 struct ParamsUseScopedRefptrCorrectly
<Tuple
<A
, B
>> {
61 enum { value
= !(NeedsScopedRefptrButGetsRawPtr
<A
>::value
||
62 NeedsScopedRefptrButGetsRawPtr
<B
>::value
) };
65 template <typename A
, typename B
, typename C
>
66 struct ParamsUseScopedRefptrCorrectly
<Tuple
<A
, B
, C
>> {
67 enum { value
= !(NeedsScopedRefptrButGetsRawPtr
<A
>::value
||
68 NeedsScopedRefptrButGetsRawPtr
<B
>::value
||
69 NeedsScopedRefptrButGetsRawPtr
<C
>::value
) };
72 template <typename A
, typename B
, typename C
, typename D
>
73 struct ParamsUseScopedRefptrCorrectly
<Tuple
<A
, B
, C
, D
>> {
74 enum { value
= !(NeedsScopedRefptrButGetsRawPtr
<A
>::value
||
75 NeedsScopedRefptrButGetsRawPtr
<B
>::value
||
76 NeedsScopedRefptrButGetsRawPtr
<C
>::value
||
77 NeedsScopedRefptrButGetsRawPtr
<D
>::value
) };
80 template <typename A
, typename B
, typename C
, typename D
, typename E
>
81 struct ParamsUseScopedRefptrCorrectly
<Tuple
<A
, B
, C
, D
, E
>> {
82 enum { value
= !(NeedsScopedRefptrButGetsRawPtr
<A
>::value
||
83 NeedsScopedRefptrButGetsRawPtr
<B
>::value
||
84 NeedsScopedRefptrButGetsRawPtr
<C
>::value
||
85 NeedsScopedRefptrButGetsRawPtr
<D
>::value
||
86 NeedsScopedRefptrButGetsRawPtr
<E
>::value
) };
89 template <typename A
, typename B
, typename C
, typename D
, typename E
,
91 struct ParamsUseScopedRefptrCorrectly
<Tuple
<A
, B
, C
, D
, E
, F
>> {
92 enum { value
= !(NeedsScopedRefptrButGetsRawPtr
<A
>::value
||
93 NeedsScopedRefptrButGetsRawPtr
<B
>::value
||
94 NeedsScopedRefptrButGetsRawPtr
<C
>::value
||
95 NeedsScopedRefptrButGetsRawPtr
<D
>::value
||
96 NeedsScopedRefptrButGetsRawPtr
<E
>::value
||
97 NeedsScopedRefptrButGetsRawPtr
<F
>::value
) };
100 template <typename A
, typename B
, typename C
, typename D
, typename E
,
101 typename F
, typename G
>
102 struct ParamsUseScopedRefptrCorrectly
<Tuple
<A
, B
, C
, D
, E
, F
, G
>> {
103 enum { value
= !(NeedsScopedRefptrButGetsRawPtr
<A
>::value
||
104 NeedsScopedRefptrButGetsRawPtr
<B
>::value
||
105 NeedsScopedRefptrButGetsRawPtr
<C
>::value
||
106 NeedsScopedRefptrButGetsRawPtr
<D
>::value
||
107 NeedsScopedRefptrButGetsRawPtr
<E
>::value
||
108 NeedsScopedRefptrButGetsRawPtr
<F
>::value
||
109 NeedsScopedRefptrButGetsRawPtr
<G
>::value
) };
112 template <typename A
, typename B
, typename C
, typename D
, typename E
,
113 typename F
, typename G
, typename H
>
114 struct ParamsUseScopedRefptrCorrectly
<Tuple
<A
, B
, C
, D
, E
, F
, G
, H
>> {
115 enum { value
= !(NeedsScopedRefptrButGetsRawPtr
<A
>::value
||
116 NeedsScopedRefptrButGetsRawPtr
<B
>::value
||
117 NeedsScopedRefptrButGetsRawPtr
<C
>::value
||
118 NeedsScopedRefptrButGetsRawPtr
<D
>::value
||
119 NeedsScopedRefptrButGetsRawPtr
<E
>::value
||
120 NeedsScopedRefptrButGetsRawPtr
<F
>::value
||
121 NeedsScopedRefptrButGetsRawPtr
<G
>::value
||
122 NeedsScopedRefptrButGetsRawPtr
<H
>::value
) };
125 } // namespace internal
129 #endif // BASE_MEMORY_RAW_SCOPED_REFPTR_MISMATCH_CHECKER_H_