xref: /llvm-project/clang/test/Analysis/inlining/placement-new-fp-suppression.cpp (revision b0914e7276bf97cb57f84fecc3a95e0d3ceeaf3e)
1*b0914e72SArtem Dergachev // RUN: %clang_analyze_cc1 -std=c++14 \
2077f13c6SCsaba Dabis // RUN:  -analyzer-checker=core.CallAndMessage \
3077f13c6SCsaba Dabis // RUN:  -analyzer-config suppress-null-return-paths=false \
4077f13c6SCsaba Dabis // RUN:  -verify %s
5*b0914e72SArtem Dergachev // RUN: %clang_analyze_cc1 -std=c++14 \
6077f13c6SCsaba Dabis // RUN:  -analyzer-checker=core.CallAndMessage \
7077f13c6SCsaba Dabis // RUN:  -DSUPPRESSED \
8077f13c6SCsaba Dabis // RUN:  -verify %s
9077f13c6SCsaba Dabis 
10077f13c6SCsaba Dabis #ifdef SUPPRESSED
11077f13c6SCsaba Dabis // expected-no-diagnostics
12077f13c6SCsaba Dabis #endif
13077f13c6SCsaba Dabis 
144d4ef2a1SCsaba Dabis #include <stdint.h>
15077f13c6SCsaba Dabis #include "../Inputs/system-header-simulator-cxx.h"
16077f13c6SCsaba Dabis 
17077f13c6SCsaba Dabis void error();
18077f13c6SCsaba Dabis void *malloc(size_t);
19077f13c6SCsaba Dabis 
20077f13c6SCsaba Dabis 
21077f13c6SCsaba Dabis // From llvm/include/llvm/Support/MathExtras.h
alignAddr(const void * Addr,size_t Alignment)22077f13c6SCsaba Dabis inline uintptr_t alignAddr(const void *Addr, size_t Alignment) {
23077f13c6SCsaba Dabis   return (((uintptr_t)Addr + Alignment - 1) & ~(uintptr_t)(Alignment - 1));
24077f13c6SCsaba Dabis }
25077f13c6SCsaba Dabis 
alignmentAdjustment(const void * Ptr,size_t Alignment)26077f13c6SCsaba Dabis inline size_t alignmentAdjustment(const void *Ptr, size_t Alignment) {
27077f13c6SCsaba Dabis   return alignAddr(Ptr, Alignment) - (uintptr_t)Ptr;
28077f13c6SCsaba Dabis }
29077f13c6SCsaba Dabis 
30077f13c6SCsaba Dabis 
31077f13c6SCsaba Dabis // From llvm/include/llvm/Support/MemAlloc.h
safe_malloc(size_t Sz)32077f13c6SCsaba Dabis inline void *safe_malloc(size_t Sz) {
33077f13c6SCsaba Dabis   void *Result = malloc(Sz);
34077f13c6SCsaba Dabis   if (Result == nullptr)
35077f13c6SCsaba Dabis     error();
36077f13c6SCsaba Dabis 
37077f13c6SCsaba Dabis   return Result;
38077f13c6SCsaba Dabis }
39077f13c6SCsaba Dabis 
40077f13c6SCsaba Dabis 
41077f13c6SCsaba Dabis // From llvm/include/llvm/Support/Allocator.h
42077f13c6SCsaba Dabis class MallocAllocator {
43077f13c6SCsaba Dabis public:
Allocate(size_t Size,size_t)44077f13c6SCsaba Dabis   void *Allocate(size_t Size, size_t /*Alignment*/) {
45077f13c6SCsaba Dabis     return safe_malloc(Size);
46077f13c6SCsaba Dabis   }
47077f13c6SCsaba Dabis };
48077f13c6SCsaba Dabis 
49077f13c6SCsaba Dabis class BumpPtrAllocator {
50077f13c6SCsaba Dabis public:
Allocate(size_t Size,size_t Alignment)51077f13c6SCsaba Dabis   void *Allocate(size_t Size, size_t Alignment) {
52077f13c6SCsaba Dabis     BytesAllocated += Size;
53077f13c6SCsaba Dabis     size_t Adjustment = alignmentAdjustment(CurPtr, Alignment);
54077f13c6SCsaba Dabis     size_t SizeToAllocate = Size;
55077f13c6SCsaba Dabis 
56077f13c6SCsaba Dabis     size_t PaddedSize = SizeToAllocate + Alignment - 1;
57077f13c6SCsaba Dabis     uintptr_t AlignedAddr = alignAddr(Allocator.Allocate(PaddedSize, 0),
58077f13c6SCsaba Dabis                                       Alignment);
59077f13c6SCsaba Dabis     char *AlignedPtr = (char*)AlignedAddr;
60077f13c6SCsaba Dabis 
61077f13c6SCsaba Dabis     return AlignedPtr;
62077f13c6SCsaba Dabis   }
63077f13c6SCsaba Dabis 
64077f13c6SCsaba Dabis private:
65077f13c6SCsaba Dabis   char *CurPtr = nullptr;
66077f13c6SCsaba Dabis   size_t BytesAllocated = 0;
67077f13c6SCsaba Dabis   MallocAllocator Allocator;
68077f13c6SCsaba Dabis };
69077f13c6SCsaba Dabis 
70077f13c6SCsaba Dabis 
71077f13c6SCsaba Dabis // From clang/include/clang/AST/ASTContextAllocate.h
72077f13c6SCsaba Dabis class ASTContext;
73077f13c6SCsaba Dabis 
74077f13c6SCsaba Dabis void *operator new(size_t Bytes, const ASTContext &C, size_t Alignment = 8);
75077f13c6SCsaba Dabis void *operator new[](size_t Bytes, const ASTContext &C, size_t Alignment = 8);
76077f13c6SCsaba Dabis 
77077f13c6SCsaba Dabis 
78077f13c6SCsaba Dabis // From clang/include/clang/AST/ASTContext.h
79077f13c6SCsaba Dabis class ASTContext {
80077f13c6SCsaba Dabis public:
Allocate(size_t Size,unsigned Align=8) const81077f13c6SCsaba Dabis   void *Allocate(size_t Size, unsigned Align = 8) const {
82077f13c6SCsaba Dabis     return BumpAlloc.Allocate(Size, Align);
83077f13c6SCsaba Dabis   }
84077f13c6SCsaba Dabis 
85077f13c6SCsaba Dabis   template <typename T>
Allocate(size_t Num=1) const86077f13c6SCsaba Dabis   T *Allocate(size_t Num = 1) const {
87077f13c6SCsaba Dabis     return static_cast<T *>(Allocate(Num * sizeof(T), alignof(T)));
88077f13c6SCsaba Dabis   }
89077f13c6SCsaba Dabis 
90077f13c6SCsaba Dabis private:
91077f13c6SCsaba Dabis   mutable BumpPtrAllocator BumpAlloc;
92077f13c6SCsaba Dabis };
93077f13c6SCsaba Dabis 
94077f13c6SCsaba Dabis 
95077f13c6SCsaba Dabis // From clang/include/clang/AST/ASTContext.h
operator new(size_t Bytes,const ASTContext & C,size_t Alignment)96077f13c6SCsaba Dabis inline void *operator new(size_t Bytes, const ASTContext &C,
97077f13c6SCsaba Dabis                           size_t Alignment /* = 8 */) {
98077f13c6SCsaba Dabis   return C.Allocate(Bytes, Alignment);
99077f13c6SCsaba Dabis }
100077f13c6SCsaba Dabis 
operator new[](size_t Bytes,const ASTContext & C,size_t Alignment)101077f13c6SCsaba Dabis inline void *operator new[](size_t Bytes, const ASTContext &C,
102077f13c6SCsaba Dabis                             size_t Alignment /* = 8 */) {
103077f13c6SCsaba Dabis   return C.Allocate(Bytes, Alignment);
104077f13c6SCsaba Dabis }
105077f13c6SCsaba Dabis 
106077f13c6SCsaba Dabis 
107077f13c6SCsaba Dabis // From clang/include/clang/AST/Attr.h
operator new(size_t Bytes,ASTContext & C,size_t Alignment=8)108077f13c6SCsaba Dabis void *operator new(size_t Bytes, ASTContext &C,
109077f13c6SCsaba Dabis                    size_t Alignment = 8) noexcept {
110077f13c6SCsaba Dabis   return ::operator new(Bytes, C, Alignment);
111077f13c6SCsaba Dabis }
112077f13c6SCsaba Dabis 
113077f13c6SCsaba Dabis 
114077f13c6SCsaba Dabis class A {
115077f13c6SCsaba Dabis public:
setValue(int value)116077f13c6SCsaba Dabis   void setValue(int value) { Value = value; }
117077f13c6SCsaba Dabis private:
118077f13c6SCsaba Dabis   int Value;
119077f13c6SCsaba Dabis };
120077f13c6SCsaba Dabis 
f(const ASTContext & C)121077f13c6SCsaba Dabis void f(const ASTContext &C) {
122077f13c6SCsaba Dabis   A *a = new (C) A;
123077f13c6SCsaba Dabis   a->setValue(13);
124077f13c6SCsaba Dabis #ifndef SUPPRESSED
125077f13c6SCsaba Dabis   // expected-warning@-2 {{Called C++ object pointer is null}}
126077f13c6SCsaba Dabis #endif
127077f13c6SCsaba Dabis }
128077f13c6SCsaba Dabis 
g(const ASTContext & C)129077f13c6SCsaba Dabis void g(const ASTContext &C) {
130077f13c6SCsaba Dabis   A *a = new (C) A[1];
131077f13c6SCsaba Dabis   a[0].setValue(13);
132077f13c6SCsaba Dabis #ifndef SUPPRESSED
133077f13c6SCsaba Dabis   // expected-warning@-2 {{Called C++ object pointer is null}}
134077f13c6SCsaba Dabis #endif
135077f13c6SCsaba Dabis }
136077f13c6SCsaba Dabis 
137