// RUN: %clang_analyze_cc1 -std=c++14 \ // RUN: -analyzer-checker=core.CallAndMessage \ // RUN: -analyzer-config suppress-null-return-paths=false \ // RUN: -verify %s // RUN: %clang_analyze_cc1 -std=c++14 \ // RUN: -analyzer-checker=core.CallAndMessage \ // RUN: -DSUPPRESSED \ // RUN: -verify %s #ifdef SUPPRESSED // expected-no-diagnostics #endif #include #include "../Inputs/system-header-simulator-cxx.h" void error(); void *malloc(size_t); // From llvm/include/llvm/Support/MathExtras.h inline uintptr_t alignAddr(const void *Addr, size_t Alignment) { return (((uintptr_t)Addr + Alignment - 1) & ~(uintptr_t)(Alignment - 1)); } inline size_t alignmentAdjustment(const void *Ptr, size_t Alignment) { return alignAddr(Ptr, Alignment) - (uintptr_t)Ptr; } // From llvm/include/llvm/Support/MemAlloc.h inline void *safe_malloc(size_t Sz) { void *Result = malloc(Sz); if (Result == nullptr) error(); return Result; } // From llvm/include/llvm/Support/Allocator.h class MallocAllocator { public: void *Allocate(size_t Size, size_t /*Alignment*/) { return safe_malloc(Size); } }; class BumpPtrAllocator { public: void *Allocate(size_t Size, size_t Alignment) { BytesAllocated += Size; size_t Adjustment = alignmentAdjustment(CurPtr, Alignment); size_t SizeToAllocate = Size; size_t PaddedSize = SizeToAllocate + Alignment - 1; uintptr_t AlignedAddr = alignAddr(Allocator.Allocate(PaddedSize, 0), Alignment); char *AlignedPtr = (char*)AlignedAddr; return AlignedPtr; } private: char *CurPtr = nullptr; size_t BytesAllocated = 0; MallocAllocator Allocator; }; // From clang/include/clang/AST/ASTContextAllocate.h class ASTContext; void *operator new(size_t Bytes, const ASTContext &C, size_t Alignment = 8); void *operator new[](size_t Bytes, const ASTContext &C, size_t Alignment = 8); // From clang/include/clang/AST/ASTContext.h class ASTContext { public: void *Allocate(size_t Size, unsigned Align = 8) const { return BumpAlloc.Allocate(Size, Align); } template T *Allocate(size_t Num = 1) const { return static_cast(Allocate(Num * sizeof(T), alignof(T))); } private: mutable BumpPtrAllocator BumpAlloc; }; // From clang/include/clang/AST/ASTContext.h inline void *operator new(size_t Bytes, const ASTContext &C, size_t Alignment /* = 8 */) { return C.Allocate(Bytes, Alignment); } inline void *operator new[](size_t Bytes, const ASTContext &C, size_t Alignment /* = 8 */) { return C.Allocate(Bytes, Alignment); } // From clang/include/clang/AST/Attr.h void *operator new(size_t Bytes, ASTContext &C, size_t Alignment = 8) noexcept { return ::operator new(Bytes, C, Alignment); } class A { public: void setValue(int value) { Value = value; } private: int Value; }; void f(const ASTContext &C) { A *a = new (C) A; a->setValue(13); #ifndef SUPPRESSED // expected-warning@-2 {{Called C++ object pointer is null}} #endif } void g(const ASTContext &C) { A *a = new (C) A[1]; a[0].setValue(13); #ifndef SUPPRESSED // expected-warning@-2 {{Called C++ object pointer is null}} #endif }