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.
4 
5 #ifndef BASE_MEMORY_RAW_SCOPED_REFPTR_MISMATCH_CHECKER_H_
6 #define BASE_MEMORY_RAW_SCOPED_REFPTR_MISMATCH_CHECKER_H_
7 
8 #include "base/memory/ref_counted.h"
9 #include "base/template_util.h"
10 #include "base/tuple.h"
11 #include "build/build_config.h"
12 
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.
19 
20 namespace base {
21 
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.
24 namespace internal {
25 
26 template <typename T>
27 struct NeedsScopedRefptrButGetsRawPtr {
28 #if defined(OS_WIN)
29   enum {
30     value = base::false_type::value
31   };
32 #else
33   enum {
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)
36     // type.
37     value = (is_pointer<T>::value &&
38              (is_convertible<T, subtle::RefCountedBase*>::value ||
39               is_convertible<T, subtle::RefCountedThreadSafeBase*>::value))
40   };
41 #endif
42 };
43 
44 template <typename Params>
45 struct ParamsUseScopedRefptrCorrectly {
46   enum { value = 0 };
47 };
48 
49 template <>
50 struct ParamsUseScopedRefptrCorrectly<Tuple<>> {
51   enum { value = 1 };
52 };
53 
54 template <typename Head, typename... Tail>
55 struct ParamsUseScopedRefptrCorrectly<Tuple<Head, Tail...>> {
56   enum { value = !NeedsScopedRefptrButGetsRawPtr<Head>::value &&
57                  ParamsUseScopedRefptrCorrectly<Tuple<Tail...>>::value };
58 };
59 
60 }  // namespace internal
61 
62 }  // namespace base
63 
64 #endif  // BASE_MEMORY_RAW_SCOPED_REFPTR_MISMATCH_CHECKER_H_
65