// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus.NewDelete -std=c++11 -verify %s // RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus.NewDeleteLeaks -DLEAKS -std=c++11 -verify %s // RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus.NewDelete -std=c++11 -DTEST_INLINABLE_ALLOCATORS -verify %s // RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus.NewDeleteLeaks -DLEAKS -std=c++11 -DTEST_INLINABLE_ALLOCATORS -verify %s // RUN: %clang_analyze_cc1 -analyzer-inline-max-stack-depth 2 -analyzer-config ipa-always-inline-size=2 -analyzer-checker=core,cplusplus.NewDelete -std=c++11 -verify %s // RUN: %clang_analyze_cc1 -analyzer-inline-max-stack-depth 2 -analyzer-config ipa-always-inline-size=2 -analyzer-checker=core,cplusplus.NewDeleteLeaks -DLEAKS -std=c++11 -verify %s // RUN: %clang_analyze_cc1 -analyzer-inline-max-stack-depth 2 -analyzer-config ipa-always-inline-size=2 -analyzer-checker=core,cplusplus.NewDelete -std=c++11 -DTEST_INLINABLE_ALLOCATORS -verify %s // RUN: %clang_analyze_cc1 -analyzer-inline-max-stack-depth 2 -analyzer-config ipa-always-inline-size=2 -analyzer-checker=core,cplusplus.NewDeleteLeaks -DLEAKS -std=c++11 -DTEST_INLINABLE_ALLOCATORS -verify %s // expected-no-diagnostics #include "Inputs/system-header-simulator-cxx.h" typedef enum memory_order { memory_order_relaxed = __ATOMIC_RELAXED, memory_order_consume = __ATOMIC_CONSUME, memory_order_acquire = __ATOMIC_ACQUIRE, memory_order_release = __ATOMIC_RELEASE, memory_order_acq_rel = __ATOMIC_ACQ_REL, memory_order_seq_cst = __ATOMIC_SEQ_CST } memory_order; class Obj { int RefCnt; public: int incRef() { return __c11_atomic_fetch_add((volatile _Atomic(int) *)&RefCnt, 1, memory_order_relaxed); } int decRef() { return __c11_atomic_fetch_sub((volatile _Atomic(int) *)&RefCnt, 1, memory_order_relaxed); } void foo(); }; class IntrusivePtr { Obj *Ptr; public: IntrusivePtr(Obj *Ptr) : Ptr(Ptr) { Ptr->incRef(); } IntrusivePtr(const IntrusivePtr &Other) : Ptr(Other.Ptr) { Ptr->incRef(); } ~IntrusivePtr() { // We should not take the path on which the object is deleted. if (Ptr->decRef() == 1) delete Ptr; } Obj *getPtr() const { return Ptr; } // no-warning }; void testDestroyLocalRefPtr() { IntrusivePtr p1(new Obj()); { IntrusivePtr p2(p1); } // p1 still maintains ownership. The object is not deleted. p1.getPtr()->foo(); // no-warning } void testDestroySymbolicRefPtr(const IntrusivePtr &p1) { { IntrusivePtr p2(p1); } // p1 still maintains ownership. The object is not deleted. p1.getPtr()->foo(); // no-warning }