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. 32 // FIXME: PostStmt<CXXDeleteExpr> should be present. 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 42 p = new int; 43 operator delete(p, 23542368); 44 // CHECK-NEXT: PreCall (operator new) [CXXAllocatorCall] 45 // CHECK-NEXT: PostCall (operator new) [CXXAllocatorCall] 46 // CHECK-NEXT: PreStmt<CXXNewExpr> 47 // CHECK-NEXT: PostStmt<CXXNewExpr> 48 // CHECK-NEXT: PreCall (operator delete) [SimpleFunctionCall] 49 // CHECK-NEXT: PostCall (operator delete) [SimpleFunctionCall] 50 51 void *v = operator new(sizeof(int[2]), std::align_val_t(2)); 52 operator delete(v, std::align_val_t(2)); 53 // CHECK-NEXT: PreCall (operator new) [SimpleFunctionCall] 54 // CHECK-NEXT: PostCall (operator new) [SimpleFunctionCall] 55 // CHECK-NEXT: PreCall (operator delete) [SimpleFunctionCall] 56 // CHECK-NEXT: PostCall (operator delete) [SimpleFunctionCall] 57 58 v = operator new(sizeof(int[2]), std::align_val_t(2)); 59 operator delete(v, 345345, std::align_val_t(2)); 60 // CHECK-NEXT: PreCall (operator new) [SimpleFunctionCall] 61 // CHECK-NEXT: PostCall (operator new) [SimpleFunctionCall] 62 // CHECK-NEXT: PreCall (operator delete) [SimpleFunctionCall] 63 // CHECK-NEXT: PostCall (operator delete) [SimpleFunctionCall] 64 65 p = new (std::nothrow) int; 66 operator delete(p, std::nothrow); 67 // CHECK-NEXT: PreCall (operator new) [CXXAllocatorCall] 68 // CHECK-NEXT: PostCall (operator new) [CXXAllocatorCall] 69 // CHECK-NEXT: PreStmt<CXXNewExpr> 70 // CHECK-NEXT: PostStmt<CXXNewExpr> 71 // CHECK-NEXT: PreCall (operator delete) [SimpleFunctionCall] 72 // CHECK-NEXT: PostCall (operator delete) [SimpleFunctionCall] 73 74 v = operator new(sizeof(int[2]), std::align_val_t(2), std::nothrow); 75 operator delete(v, std::align_val_t(2), std::nothrow); 76 // CHECK-NEXT: PreCall (operator new) [SimpleFunctionCall] 77 // CHECK-NEXT: PostCall (operator new) [SimpleFunctionCall] 78 // CHECK-NEXT: PreCall (operator delete) [SimpleFunctionCall] 79 // CHECK-NEXT: PostCall (operator delete) [SimpleFunctionCall] 80 } 81 82 { 83 int *p = new int[2]; 84 delete[] p; 85 // CHECK-NEXT: PreCall (operator new[]) [CXXAllocatorCall] 86 // CHECK-NEXT: PostCall (operator new[]) [CXXAllocatorCall] 87 // CHECK-NEXT: PreStmt<CXXNewExpr> 88 // CHECK-NEXT: PostStmt<CXXNewExpr> 89 // CHECK-NEXT: PreStmt<CXXDeleteExpr> 90 91 p = new int[2]; 92 operator delete[](p, 23542368); 93 // CHECK-NEXT: PreCall (operator new[]) [CXXAllocatorCall] 94 // CHECK-NEXT: PostCall (operator new[]) [CXXAllocatorCall] 95 // CHECK-NEXT: PreStmt<CXXNewExpr> 96 // CHECK-NEXT: PostStmt<CXXNewExpr> 97 // CHECK-NEXT: PreCall (operator delete[]) [SimpleFunctionCall] 98 // CHECK-NEXT: PostCall (operator delete[]) [SimpleFunctionCall] 99 100 void *v = operator new[](sizeof(int[2]), std::align_val_t(2)); 101 operator delete[](v, std::align_val_t(2)); 102 // CHECK-NEXT: PreCall (operator new[]) [SimpleFunctionCall] 103 // CHECK-NEXT: PostCall (operator new[]) [SimpleFunctionCall] 104 // CHECK-NEXT: PreCall (operator delete[]) [SimpleFunctionCall] 105 // CHECK-NEXT: PostCall (operator delete[]) [SimpleFunctionCall] 106 107 v = operator new[](sizeof(int[2]), std::align_val_t(2)); 108 operator delete[](v, 345345, std::align_val_t(2)); 109 // CHECK-NEXT: PreCall (operator new[]) [SimpleFunctionCall] 110 // CHECK-NEXT: PostCall (operator new[]) [SimpleFunctionCall] 111 // CHECK-NEXT: PreCall (operator delete[]) [SimpleFunctionCall] 112 // CHECK-NEXT: PostCall (operator delete[]) [SimpleFunctionCall] 113 114 p = new (std::nothrow) int[2]; 115 operator delete[](p, std::nothrow); 116 // CHECK-NEXT: PreCall (operator new[]) [CXXAllocatorCall] 117 // CHECK-NEXT: PostCall (operator new[]) [CXXAllocatorCall] 118 // CHECK-NEXT: PreStmt<CXXNewExpr> 119 // CHECK-NEXT: PostStmt<CXXNewExpr> 120 // CHECK-NEXT: PreCall (operator delete[]) [SimpleFunctionCall] 121 // CHECK-NEXT: PostCall (operator delete[]) [SimpleFunctionCall] 122 123 v = operator new[](sizeof(int[2]), std::align_val_t(2), std::nothrow); 124 operator delete[](v, std::align_val_t(2), std::nothrow); 125 // CHECK-NEXT: PreCall (operator new[]) [SimpleFunctionCall] 126 // CHECK-NEXT: PostCall (operator new[]) [SimpleFunctionCall] 127 // CHECK-NEXT: PreCall (operator delete[]) [SimpleFunctionCall] 128 // CHECK-NEXT: PostCall (operator delete[]) [SimpleFunctionCall] 129 } 130 } 131