From 7c87290fed96e7620b3702bc9435db6bc957d92c Mon Sep 17 00:00:00 2001 From: "jamesr@chromium.org" Date: Wed, 2 Dec 2009 01:44:30 +0000 Subject: Tries to catch callbacks expecting scoped_refptr 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 --- base/raw_scoped_refptr_mismatch_checker.h | 170 ++++++++++++++++++++++++++++++ 1 file changed, 170 insertions(+) create mode 100644 base/raw_scoped_refptr_mismatch_checker.h (limited to 'base/raw_scoped_refptr_mismatch_checker.h') 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 +struct ExpectsScopedRefptrButGetsRawPtr { + enum { value = 0 }; +}; + +template +struct ExpectsScopedRefptrButGetsRawPtr, B*> { + enum { value = 1 }; +}; + +template +struct FunctionUsesScopedRefptrCorrectly { + enum { value = 1 }; +}; + +template +struct FunctionUsesScopedRefptrCorrectly > { + enum { value = !ExpectsScopedRefptrButGetsRawPtr::value }; +}; + +template +struct FunctionUsesScopedRefptrCorrectly > { + enum { value = !(ExpectsScopedRefptrButGetsRawPtr::value || + ExpectsScopedRefptrButGetsRawPtr::value) }; +}; + +template +struct FunctionUsesScopedRefptrCorrectly > { + enum { value = !(ExpectsScopedRefptrButGetsRawPtr::value || + ExpectsScopedRefptrButGetsRawPtr::value || + ExpectsScopedRefptrButGetsRawPtr::value) }; +}; + +template +struct FunctionUsesScopedRefptrCorrectly > { + enum { value = !(ExpectsScopedRefptrButGetsRawPtr::value || + ExpectsScopedRefptrButGetsRawPtr::value || + ExpectsScopedRefptrButGetsRawPtr::value || + ExpectsScopedRefptrButGetsRawPtr::value) }; +}; + +template +struct FunctionUsesScopedRefptrCorrectly > { + enum { value = !(ExpectsScopedRefptrButGetsRawPtr::value || + ExpectsScopedRefptrButGetsRawPtr::value || + ExpectsScopedRefptrButGetsRawPtr::value || + ExpectsScopedRefptrButGetsRawPtr::value || + ExpectsScopedRefptrButGetsRawPtr::value) }; +}; + +template +struct FunctionUsesScopedRefptrCorrectly > { + enum { value = !(ExpectsScopedRefptrButGetsRawPtr::value || + ExpectsScopedRefptrButGetsRawPtr::value || + ExpectsScopedRefptrButGetsRawPtr::value || + ExpectsScopedRefptrButGetsRawPtr::value || + ExpectsScopedRefptrButGetsRawPtr::value || + ExpectsScopedRefptrButGetsRawPtr::value) }; +}; + +template +struct FunctionUsesScopedRefptrCorrectly > { + enum { value = !(ExpectsScopedRefptrButGetsRawPtr::value || + ExpectsScopedRefptrButGetsRawPtr::value || + ExpectsScopedRefptrButGetsRawPtr::value || + ExpectsScopedRefptrButGetsRawPtr::value || + ExpectsScopedRefptrButGetsRawPtr::value || + ExpectsScopedRefptrButGetsRawPtr::value || + ExpectsScopedRefptrButGetsRawPtr::value) }; +}; + +template +struct MethodUsesScopedRefptrCorrectly { + enum { value = 1 }; +}; + +template +struct MethodUsesScopedRefptrCorrectly > { + enum { value = !ExpectsScopedRefptrButGetsRawPtr::value }; +}; + +template +struct MethodUsesScopedRefptrCorrectly > { + enum { value = !(ExpectsScopedRefptrButGetsRawPtr::value || + ExpectsScopedRefptrButGetsRawPtr::value) }; +}; + +template +struct MethodUsesScopedRefptrCorrectly > { + enum { value = !(ExpectsScopedRefptrButGetsRawPtr::value || + ExpectsScopedRefptrButGetsRawPtr::value || + ExpectsScopedRefptrButGetsRawPtr::value) }; +}; + +template +struct MethodUsesScopedRefptrCorrectly > { + enum { value = !(ExpectsScopedRefptrButGetsRawPtr::value || + ExpectsScopedRefptrButGetsRawPtr::value || + ExpectsScopedRefptrButGetsRawPtr::value || + ExpectsScopedRefptrButGetsRawPtr::value) }; +}; + +template +struct MethodUsesScopedRefptrCorrectly > { + enum { value = !(ExpectsScopedRefptrButGetsRawPtr::value || + ExpectsScopedRefptrButGetsRawPtr::value || + ExpectsScopedRefptrButGetsRawPtr::value || + ExpectsScopedRefptrButGetsRawPtr::value || + ExpectsScopedRefptrButGetsRawPtr::value) }; +}; + +template +struct MethodUsesScopedRefptrCorrectly > { + enum { value = !(ExpectsScopedRefptrButGetsRawPtr::value || + ExpectsScopedRefptrButGetsRawPtr::value || + ExpectsScopedRefptrButGetsRawPtr::value || + ExpectsScopedRefptrButGetsRawPtr::value || + ExpectsScopedRefptrButGetsRawPtr::value || + ExpectsScopedRefptrButGetsRawPtr::value) }; +}; + +template +struct MethodUsesScopedRefptrCorrectly > { + enum { value = !(ExpectsScopedRefptrButGetsRawPtr::value || + ExpectsScopedRefptrButGetsRawPtr::value || + ExpectsScopedRefptrButGetsRawPtr::value || + ExpectsScopedRefptrButGetsRawPtr::value || + ExpectsScopedRefptrButGetsRawPtr::value || + ExpectsScopedRefptrButGetsRawPtr::value || + ExpectsScopedRefptrButGetsRawPtr::value) }; +}; + +#endif // BASE_RAW_SCOPED_REFPTR_MISMATCH_CHECKER_H_ -- cgit v1.1