1 // RUN: %clang_analyze_cc1 -std=c++20 -fblocks -verify %s \ 2 // RUN: -analyzer-checker=core \ 3 // RUN: -analyzer-checker=debug.AnalysisOrder \ 4 // RUN: -analyzer-config debug.AnalysisOrder:PreStmtCXXNewExpr=true \ 5 // RUN: -analyzer-config debug.AnalysisOrder:PostStmtCXXNewExpr=true \ 6 // RUN: -analyzer-config debug.AnalysisOrder:PreStmtCXXDeleteExpr=true \ 7 // RUN: -analyzer-config debug.AnalysisOrder:PostStmtCXXDeleteExpr=true \ 8 // RUN: -analyzer-config debug.AnalysisOrder:PreCall=true \ 9 // RUN: -analyzer-config debug.AnalysisOrder:PostCall=true \ 10 // RUN: 2>&1 | FileCheck %s 11 12 // expected-no-diagnostics 13 14 #include "Inputs/system-header-simulator-cxx.h" 15 16 void f() { 17 // C++20 standard draft 17.6.1.15: 18 // Required behavior: A call to an operator delete with a size parameter may 19 // be changed to a call to the corresponding operator delete without a size 20 // parameter, without affecting memory allocation. [ Note: A conforming 21 // implementation is for operator delete(void* ptr, size_t size) to simply 22 // call operator delete(ptr). — end note ] 23 // 24 // C++20 standard draft 17.6.1.24, about nothrow operator delete: 25 // void operator delete(void* ptr, const std::nothrow_t&) noexcept; 26 // void operator delete(void* ptr, std::align_val_t alignment, 27 // const std::nothrow_t&) noexcept; 28 // Default behavior: Calls operator delete(ptr), or operator delete(ptr, 29 // alignment), respectively. 30 31 // FIXME: All calls to operator new should be CXXAllocatorCall, and calls to 32 // operator delete should be CXXDeallocatorCall. 33 { 34 int *p = new int; 35 delete p; 36 // CHECK: PreCall (operator new) [CXXAllocatorCall] 37 // CHECK-NEXT: PostCall (operator new) [CXXAllocatorCall] 38 // CHECK-NEXT: PreStmt<CXXNewExpr> 39 // CHECK-NEXT: PostStmt<CXXNewExpr> 40 // CHECK-NEXT: PreStmt<CXXDeleteExpr> 41 // CHECK-NEXT: PostStmt<CXXDeleteExpr> 42 // CHECK-NEXT: PreCall (operator delete) [CXXDeallocatorCall] 43 // CHECK-NEXT: PostCall (operator delete) [CXXDeallocatorCall] 44 45 p = new int; 46 operator delete(p, 23542368); 47 // CHECK-NEXT: PreCall (operator new) [CXXAllocatorCall] 48 // CHECK-NEXT: PostCall (operator new) [CXXAllocatorCall] 49 // CHECK-NEXT: PreStmt<CXXNewExpr> 50 // CHECK-NEXT: PostStmt<CXXNewExpr> 51 // CHECK-NEXT: PreCall (operator delete) [SimpleFunctionCall] 52 // CHECK-NEXT: PostCall (operator delete) [SimpleFunctionCall] 53 54 void *v = operator new(sizeof(int[2]), std::align_val_t(2)); 55 operator delete(v, std::align_val_t(2)); 56 // CHECK-NEXT: PreCall (operator new) [SimpleFunctionCall] 57 // CHECK-NEXT: PostCall (operator new) [SimpleFunctionCall] 58 // CHECK-NEXT: PreCall (operator delete) [SimpleFunctionCall] 59 // CHECK-NEXT: PostCall (operator delete) [SimpleFunctionCall] 60 61 v = operator new(sizeof(int[2]), std::align_val_t(2)); 62 operator delete(v, 345345, std::align_val_t(2)); 63 // CHECK-NEXT: PreCall (operator new) [SimpleFunctionCall] 64 // CHECK-NEXT: PostCall (operator new) [SimpleFunctionCall] 65 // CHECK-NEXT: PreCall (operator delete) [SimpleFunctionCall] 66 // CHECK-NEXT: PostCall (operator delete) [SimpleFunctionCall] 67 68 p = new (std::nothrow) int; 69 operator delete(p, std::nothrow); 70 // CHECK-NEXT: PreCall (operator new) [CXXAllocatorCall] 71 // CHECK-NEXT: PostCall (operator new) [CXXAllocatorCall] 72 // CHECK-NEXT: PreStmt<CXXNewExpr> 73 // CHECK-NEXT: PostStmt<CXXNewExpr> 74 // CHECK-NEXT: PreCall (operator delete) [SimpleFunctionCall] 75 // CHECK-NEXT: PostCall (operator delete) [SimpleFunctionCall] 76 77 v = operator new(sizeof(int[2]), std::align_val_t(2), std::nothrow); 78 operator delete(v, std::align_val_t(2), std::nothrow); 79 // CHECK-NEXT: PreCall (operator new) [SimpleFunctionCall] 80 // CHECK-NEXT: PostCall (operator new) [SimpleFunctionCall] 81 // CHECK-NEXT: PreCall (operator delete) [SimpleFunctionCall] 82 // CHECK-NEXT: PostCall (operator delete) [SimpleFunctionCall] 83 } 84 85 { 86 int *p = new int[2]; 87 delete[] p; 88 // CHECK-NEXT: PreCall (operator new[]) [CXXAllocatorCall] 89 // CHECK-NEXT: PostCall (operator new[]) [CXXAllocatorCall] 90 // CHECK-NEXT: PreStmt<CXXNewExpr> 91 // CHECK-NEXT: PostStmt<CXXNewExpr> 92 // CHECK-NEXT: PreStmt<CXXDeleteExpr> 93 // CHECK-NEXT: PostStmt<CXXDeleteExpr> 94 // CHECK-NEXT: PreCall (operator delete[]) [CXXDeallocatorCall] 95 // CHECK-NEXT: PostCall (operator delete[]) [CXXDeallocatorCall] 96 97 p = new int[2]; 98 operator delete[](p, 23542368); 99 // CHECK-NEXT: PreCall (operator new[]) [CXXAllocatorCall] 100 // CHECK-NEXT: PostCall (operator new[]) [CXXAllocatorCall] 101 // CHECK-NEXT: PreStmt<CXXNewExpr> 102 // CHECK-NEXT: PostStmt<CXXNewExpr> 103 // CHECK-NEXT: PreCall (operator delete[]) [SimpleFunctionCall] 104 // CHECK-NEXT: PostCall (operator delete[]) [SimpleFunctionCall] 105 106 void *v = operator new[](sizeof(int[2]), std::align_val_t(2)); 107 operator delete[](v, std::align_val_t(2)); 108 // CHECK-NEXT: PreCall (operator new[]) [SimpleFunctionCall] 109 // CHECK-NEXT: PostCall (operator new[]) [SimpleFunctionCall] 110 // CHECK-NEXT: PreCall (operator delete[]) [SimpleFunctionCall] 111 // CHECK-NEXT: PostCall (operator delete[]) [SimpleFunctionCall] 112 113 v = operator new[](sizeof(int[2]), std::align_val_t(2)); 114 operator delete[](v, 345345, std::align_val_t(2)); 115 // CHECK-NEXT: PreCall (operator new[]) [SimpleFunctionCall] 116 // CHECK-NEXT: PostCall (operator new[]) [SimpleFunctionCall] 117 // CHECK-NEXT: PreCall (operator delete[]) [SimpleFunctionCall] 118 // CHECK-NEXT: PostCall (operator delete[]) [SimpleFunctionCall] 119 120 p = new (std::nothrow) int[2]; 121 operator delete[](p, std::nothrow); 122 // CHECK-NEXT: PreCall (operator new[]) [CXXAllocatorCall] 123 // CHECK-NEXT: PostCall (operator new[]) [CXXAllocatorCall] 124 // CHECK-NEXT: PreStmt<CXXNewExpr> 125 // CHECK-NEXT: PostStmt<CXXNewExpr> 126 // CHECK-NEXT: PreCall (operator delete[]) [SimpleFunctionCall] 127 // CHECK-NEXT: PostCall (operator delete[]) [SimpleFunctionCall] 128 129 v = operator new[](sizeof(int[2]), std::align_val_t(2), std::nothrow); 130 operator delete[](v, std::align_val_t(2), std::nothrow); 131 // CHECK-NEXT: PreCall (operator new[]) [SimpleFunctionCall] 132 // CHECK-NEXT: PostCall (operator new[]) [SimpleFunctionCall] 133 // CHECK-NEXT: PreCall (operator delete[]) [SimpleFunctionCall] 134 // CHECK-NEXT: PostCall (operator delete[]) [SimpleFunctionCall] 135 } 136 } 137