#include using namespace mozilla; struct RefCountedBase { void AddRef(); void Release(); void method_test(); }; struct RefCountedBaseHolder { RefPtr GetRefCountedBase() const { return mRefCountedBase; } private: RefPtr mRefCountedBase = MakeRefPtr(); }; void test_arrow_temporary_new_refptr_function_style_cast() { RefPtr(new RefCountedBase())->method_test(); // expected-warning {{performance issue: temporary 'RefPtr' is only dereferenced here once which involves short-lived AddRef/Release calls}} } void test_arrow_temporary_new_refptr_brace() { RefPtr{new RefCountedBase()}->method_test(); // expected-warning {{performance issue: temporary 'RefPtr' is only dereferenced here once which involves short-lived AddRef/Release calls}} } void test_arrow_temporary_new_c_style_cast() { ((RefPtr)(new RefCountedBase()))->method_test(); // expected-warning {{performance issue: temporary 'RefPtr' is only dereferenced here once which involves short-lived AddRef/Release calls}} } void test_arrow_temporary_new_static_cast() { static_cast>(new RefCountedBase())->method_test(); // expected-warning {{performance issue: temporary 'RefPtr' is only dereferenced here once which involves short-lived AddRef/Release calls}} } void test_arrow_temporary_new_refptr_makerefptr() { MakeRefPtr()->method_test(); // expected-warning {{performance issue: temporary 'RefPtr' is only dereferenced here once which involves short-lived AddRef/Release calls}} } void test_arrow_temporary_get_refptr_from_member_function() { const RefCountedBaseHolder holder; holder.GetRefCountedBase()->method_test(); // expected-warning {{performance issue: temporary 'RefPtr' is only dereferenced here once which involves short-lived AddRef/Release calls}} expected-note {{consider changing function RefCountedBaseHolder::GetRefCountedBase to return a raw reference instead}} } void test_ref(RefCountedBase &aRefCountedBase); void test_star_temporary_new_refptr_function_style_cast() { // TODO: Should we warn about operator* as well? test_ref(*RefPtr(new RefCountedBase())); }