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