1 // Copyright (c) 2011 Google Inc. All rights reserved. 2 // 3 // Redistribution and use in source and binary forms, with or without 4 // modification, are permitted provided that the following conditions are 5 // met: 6 // 7 // * Redistributions of source code must retain the above copyright 8 // notice, this list of conditions and the following disclaimer. 9 // * Redistributions in binary form must reproduce the above 10 // copyright notice, this list of conditions and the following disclaimer 11 // in the documentation and/or other materials provided with the 12 // distribution. 13 // * Neither the name of Google Inc. nor the name Chromium Embedded 14 // Framework nor the names of its contributors may be used to endorse 15 // or promote products derived from this software without specific prior 16 // written permission. 17 // 18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 30 // Do not include this header file directly. Use base/cef_callback.h instead. 31 32 #ifndef CEF_INCLUDE_BASE_INTERNAL_CEF_RAW_SCOPED_REFPTR_MISMATCH_CHECKER_H_ 33 #define CEF_INCLUDE_BASE_INTERNAL_CEF_RAW_SCOPED_REFPTR_MISMATCH_CHECKER_H_ 34 35 #include "include/base/cef_build.h" 36 #include "include/base/cef_ref_counted.h" 37 #include "include/base/cef_template_util.h" 38 #include "include/base/cef_tuple.h" 39 40 // It is dangerous to post a task with a T* argument where T is a subtype of 41 // RefCounted(Base|ThreadSafeBase), since by the time the parameter is used, the 42 // object may already have been deleted since it was not held with a 43 // scoped_refptr. Example: http://crbug.com/27191 44 // The following set of traits are designed to generate a compile error 45 // whenever this antipattern is attempted. 46 47 namespace base { 48 49 namespace cef_internal { 50 51 template <typename T> 52 struct NeedsScopedRefptrButGetsRawPtr { 53 #if defined(OS_WIN) 54 enum { value = base::false_type::value }; 55 #else 56 enum { 57 // Human readable translation: you needed to be a scoped_refptr if you are a 58 // raw pointer type and are convertible to a RefCounted(Base|ThreadSafeBase) 59 // type. 60 value = (is_pointer<T>::value && 61 (is_convertible<T, subtle::RefCountedBase*>::value || 62 is_convertible<T, subtle::RefCountedThreadSafeBase*>::value)) 63 }; 64 #endif 65 }; 66 67 template <typename Params> 68 struct ParamsUseScopedRefptrCorrectly { 69 enum { value = 0 }; 70 }; 71 72 template <> 73 struct ParamsUseScopedRefptrCorrectly<Tuple0> { 74 enum { value = 1 }; 75 }; 76 77 template <typename A> 78 struct ParamsUseScopedRefptrCorrectly<Tuple1<A>> { 79 enum { value = !NeedsScopedRefptrButGetsRawPtr<A>::value }; 80 }; 81 82 template <typename A, typename B> 83 struct ParamsUseScopedRefptrCorrectly<Tuple2<A, B>> { 84 enum { 85 value = !(NeedsScopedRefptrButGetsRawPtr<A>::value || 86 NeedsScopedRefptrButGetsRawPtr<B>::value) 87 }; 88 }; 89 90 template <typename A, typename B, typename C> 91 struct ParamsUseScopedRefptrCorrectly<Tuple3<A, B, C>> { 92 enum { 93 value = !(NeedsScopedRefptrButGetsRawPtr<A>::value || 94 NeedsScopedRefptrButGetsRawPtr<B>::value || 95 NeedsScopedRefptrButGetsRawPtr<C>::value) 96 }; 97 }; 98 99 template <typename A, typename B, typename C, typename D> 100 struct ParamsUseScopedRefptrCorrectly<Tuple4<A, B, C, D>> { 101 enum { 102 value = !(NeedsScopedRefptrButGetsRawPtr<A>::value || 103 NeedsScopedRefptrButGetsRawPtr<B>::value || 104 NeedsScopedRefptrButGetsRawPtr<C>::value || 105 NeedsScopedRefptrButGetsRawPtr<D>::value) 106 }; 107 }; 108 109 template <typename A, typename B, typename C, typename D, typename E> 110 struct ParamsUseScopedRefptrCorrectly<Tuple5<A, B, C, D, E>> { 111 enum { 112 value = !(NeedsScopedRefptrButGetsRawPtr<A>::value || 113 NeedsScopedRefptrButGetsRawPtr<B>::value || 114 NeedsScopedRefptrButGetsRawPtr<C>::value || 115 NeedsScopedRefptrButGetsRawPtr<D>::value || 116 NeedsScopedRefptrButGetsRawPtr<E>::value) 117 }; 118 }; 119 120 template <typename A, 121 typename B, 122 typename C, 123 typename D, 124 typename E, 125 typename F> 126 struct ParamsUseScopedRefptrCorrectly<Tuple6<A, B, C, D, E, F>> { 127 enum { 128 value = !(NeedsScopedRefptrButGetsRawPtr<A>::value || 129 NeedsScopedRefptrButGetsRawPtr<B>::value || 130 NeedsScopedRefptrButGetsRawPtr<C>::value || 131 NeedsScopedRefptrButGetsRawPtr<D>::value || 132 NeedsScopedRefptrButGetsRawPtr<E>::value || 133 NeedsScopedRefptrButGetsRawPtr<F>::value) 134 }; 135 }; 136 137 template <typename A, 138 typename B, 139 typename C, 140 typename D, 141 typename E, 142 typename F, 143 typename G> 144 struct ParamsUseScopedRefptrCorrectly<Tuple7<A, B, C, D, E, F, G>> { 145 enum { 146 value = !(NeedsScopedRefptrButGetsRawPtr<A>::value || 147 NeedsScopedRefptrButGetsRawPtr<B>::value || 148 NeedsScopedRefptrButGetsRawPtr<C>::value || 149 NeedsScopedRefptrButGetsRawPtr<D>::value || 150 NeedsScopedRefptrButGetsRawPtr<E>::value || 151 NeedsScopedRefptrButGetsRawPtr<F>::value || 152 NeedsScopedRefptrButGetsRawPtr<G>::value) 153 }; 154 }; 155 156 template <typename A, 157 typename B, 158 typename C, 159 typename D, 160 typename E, 161 typename F, 162 typename G, 163 typename H> 164 struct ParamsUseScopedRefptrCorrectly<Tuple8<A, B, C, D, E, F, G, H>> { 165 enum { 166 value = !(NeedsScopedRefptrButGetsRawPtr<A>::value || 167 NeedsScopedRefptrButGetsRawPtr<B>::value || 168 NeedsScopedRefptrButGetsRawPtr<C>::value || 169 NeedsScopedRefptrButGetsRawPtr<D>::value || 170 NeedsScopedRefptrButGetsRawPtr<E>::value || 171 NeedsScopedRefptrButGetsRawPtr<F>::value || 172 NeedsScopedRefptrButGetsRawPtr<G>::value || 173 NeedsScopedRefptrButGetsRawPtr<H>::value) 174 }; 175 }; 176 177 } // namespace cef_internal 178 179 } // namespace base 180 181 #endif // CEF_INCLUDE_BASE_INTERNAL_CEF_RAW_SCOPED_REFPTR_MISMATCH_CHECKER_H_ 182