brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.8 KiB · cb0d5aa Raw
225 lines · cpp
1// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus.NewDelete -std=c++11 -verify %s2// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus.NewDeleteLeaks -DLEAKS -std=c++11 -verify %s3// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus.NewDelete -std=c++11 -DTEST_INLINABLE_ALLOCATORS -verify %s4// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus.NewDeleteLeaks -DLEAKS -std=c++11 -DTEST_INLINABLE_ALLOCATORS -verify %s5// 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 %s6// 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 %s7// 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 %s8// 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 %s9 10// expected-no-diagnostics11 12#include "Inputs/system-header-simulator-cxx.h"13 14typedef enum memory_order {15  memory_order_relaxed = __ATOMIC_RELAXED,16  memory_order_consume = __ATOMIC_CONSUME,17  memory_order_acquire = __ATOMIC_ACQUIRE,18  memory_order_release = __ATOMIC_RELEASE,19  memory_order_acq_rel = __ATOMIC_ACQ_REL,20  memory_order_seq_cst = __ATOMIC_SEQ_CST21} memory_order;22 23class RawObj {24  int RefCnt;25 26public:27  int incRef() {28    return __c11_atomic_fetch_add((volatile _Atomic(int) *)&RefCnt, 1,29                                  memory_order_relaxed);30  }31 32  int decRef() {33    return __c11_atomic_fetch_sub((volatile _Atomic(int) *)&RefCnt, 1,34                                  memory_order_relaxed);35  }36 37  void foo();38};39 40class StdAtomicObj {41  std::atomic<int> RefCnt;42 43public:44  int incRef() {45    return ++RefCnt;46  }47 48  int decRef() {49    return --RefCnt;50  }51 52  void foo();53};54 55template <typename T>56class IntrusivePtr {57  T *Ptr;58 59public:60  IntrusivePtr(T *Ptr) : Ptr(Ptr) {61    Ptr->incRef();62  }63 64  IntrusivePtr(const IntrusivePtr &Other) : Ptr(Other.Ptr) {65    Ptr->incRef();66  }67 68  ~IntrusivePtr() {69  // We should not take the path on which the object is deleted.70    if (Ptr->decRef() == 1)71      delete Ptr;72  }73 74  T *getPtr() const { return Ptr; } // no-warning75};76 77// Also IntrusivePtr but let's dodge name-based heuristics.78template <typename T>79class DifferentlyNamed {80  T *Ptr;81 82public:83  DifferentlyNamed(T *Ptr) : Ptr(Ptr) {84    Ptr->incRef();85  }86 87  DifferentlyNamed(const DifferentlyNamed &Other) : Ptr(Other.Ptr) {88    Ptr->incRef();89  }90 91  ~DifferentlyNamed() {92  // We should not take the path on which the object is deleted.93    if (Ptr->decRef() == 1)94      delete Ptr;95  }96 97  T *getPtr() const { return Ptr; } // no-warning98};99 100// Also IntrusivePtr with different name and outline release in destructor101template <typename T>102class DifferentlyNamedOutlineRelease {103  T *Ptr;104 105public:106  DifferentlyNamedOutlineRelease(T *Ptr) : Ptr(Ptr) {107    Ptr->incRef();108  }109 110  DifferentlyNamedOutlineRelease(const DifferentlyNamedOutlineRelease &Other) : Ptr(Other.Ptr) {111    Ptr->incRef();112  }113 114  void releasePtr(void) {115      delete Ptr;116  }117 118  ~DifferentlyNamedOutlineRelease() {119    if (Ptr->decRef() == 1)120      releasePtr();121  }122 123  T *getPtr() const { return Ptr; } // no-warning124};125 126void testDestroyLocalRefPtr() {127  IntrusivePtr<RawObj> p1(new RawObj());128  {129    IntrusivePtr<RawObj> p2(p1);130  }131 132  // p1 still maintains ownership. The object is not deleted.133  p1.getPtr()->foo(); // no-warning134}135 136void testDestroySymbolicRefPtr(const IntrusivePtr<RawObj> &p1) {137  {138    IntrusivePtr<RawObj> p2(p1);139  }140 141  // p1 still maintains ownership. The object is not deleted.142  p1.getPtr()->foo(); // no-warning143}144 145void testDestroyLocalRefPtrWithAtomics() {146  IntrusivePtr<StdAtomicObj> p1(new StdAtomicObj());147  {148    IntrusivePtr<StdAtomicObj> p2(p1);149  }150 151  // p1 still maintains ownership. The object is not deleted.152  p1.getPtr()->foo(); // no-warning153}154 155 156void testDestroyLocalRefPtrWithAtomics(const IntrusivePtr<StdAtomicObj> &p1) {157  {158    IntrusivePtr<StdAtomicObj> p2(p1);159  }160 161  // p1 still maintains ownership. The object is not deleted.162  p1.getPtr()->foo(); // no-warning163}164 165void testDestroyLocalRefPtrDifferentlyNamed() {166  DifferentlyNamed<RawObj> p1(new RawObj());167  {168    DifferentlyNamed<RawObj> p2(p1);169  }170 171  // p1 still maintains ownership. The object is not deleted.172  p1.getPtr()->foo(); // no-warning173}174 175void testDestroySymbolicRefPtrDifferentlyNamed(176    const DifferentlyNamed<RawObj> &p1) {177  {178    DifferentlyNamed<RawObj> p2(p1);179  }180 181  // p1 still maintains ownership. The object is not deleted.182  p1.getPtr()->foo(); // no-warning183}184 185void testDestroyLocalRefPtrWithAtomicsDifferentlyNamed() {186  DifferentlyNamed<StdAtomicObj> p1(new StdAtomicObj());187  {188    DifferentlyNamed<StdAtomicObj> p2(p1);189  }190 191  // p1 still maintains ownership. The object is not deleted.192  p1.getPtr()->foo(); // no-warning193}194 195 196void testDestroyLocalRefPtrWithAtomicsDifferentlyNamed(197    const DifferentlyNamed<StdAtomicObj> &p1) {198  {199    DifferentlyNamed<StdAtomicObj> p2(p1);200  }201 202  // p1 still maintains ownership. The object is not deleted.203  p1.getPtr()->foo(); // no-warning204}205 206void testDestroyLocalRefPtrWithOutlineRelease() {207  DifferentlyNamedOutlineRelease <RawObj> p1(new RawObj());208  {209    DifferentlyNamedOutlineRelease <RawObj> p2(p1);210  }211 212  // p1 still maintains ownership. The object is not deleted.213  p1.getPtr()->foo(); // no-warning214}215 216void testDestroySymbolicRefPtrWithOutlineRelease(217    const DifferentlyNamedOutlineRelease<RawObj> &p1) {218  {219    DifferentlyNamedOutlineRelease <RawObj> p2(p1);220  }221 222  // p1 still maintains ownership. The object is not deleted.223  p1.getPtr()->foo(); // no-warning224}225