1*ccae43a2SGeorge Burgess IV //===- MemoryBuiltinsTest.cpp - Tests for utilities in MemoryBuiltins.h ---===//
2*ccae43a2SGeorge Burgess IV //
3*ccae43a2SGeorge Burgess IV //                     The LLVM Compiler Infrastructure
4*ccae43a2SGeorge Burgess IV //
5*ccae43a2SGeorge Burgess IV // This file is distributed under the University of Illinois Open Source
6*ccae43a2SGeorge Burgess IV // License. See LICENSE.TXT for details.
7*ccae43a2SGeorge Burgess IV //
8*ccae43a2SGeorge Burgess IV //===----------------------------------------------------------------------===//
9*ccae43a2SGeorge Burgess IV 
10*ccae43a2SGeorge Burgess IV #include "llvm/Analysis/MemoryBuiltins.h"
11*ccae43a2SGeorge Burgess IV #include "llvm/IR/Attributes.h"
12*ccae43a2SGeorge Burgess IV #include "llvm/IR/Constants.h"
13*ccae43a2SGeorge Burgess IV #include "llvm/IR/Function.h"
14*ccae43a2SGeorge Burgess IV #include "llvm/IR/LLVMContext.h"
15*ccae43a2SGeorge Burgess IV #include "llvm/IR/Module.h"
16*ccae43a2SGeorge Burgess IV #include "gtest/gtest.h"
17*ccae43a2SGeorge Burgess IV 
18*ccae43a2SGeorge Burgess IV using namespace llvm;
19*ccae43a2SGeorge Burgess IV 
20*ccae43a2SGeorge Burgess IV namespace {
21*ccae43a2SGeorge Burgess IV // allocsize should not imply that a function is a traditional allocation
22*ccae43a2SGeorge Burgess IV // function (e.g. that can be optimized out/...); it just tells us how many
23*ccae43a2SGeorge Burgess IV // bytes exist at the pointer handed back by the function.
24*ccae43a2SGeorge Burgess IV TEST(AllocSize, AllocationBuiltinsTest) {
25*ccae43a2SGeorge Burgess IV   LLVMContext Context;
26*ccae43a2SGeorge Burgess IV   Module M("", Context);
27*ccae43a2SGeorge Burgess IV   IntegerType *ArgTy = Type::getInt32Ty(Context);
28*ccae43a2SGeorge Burgess IV 
29*ccae43a2SGeorge Burgess IV   Function *AllocSizeFn = Function::Create(
30*ccae43a2SGeorge Burgess IV       FunctionType::get(Type::getInt8PtrTy(Context), {ArgTy}, false),
31*ccae43a2SGeorge Burgess IV       GlobalValue::ExternalLinkage, "F", &M);
32*ccae43a2SGeorge Burgess IV 
33*ccae43a2SGeorge Burgess IV   AllocSizeFn->addFnAttr(Attribute::getWithAllocSizeArgs(Context, 1, None));
34*ccae43a2SGeorge Burgess IV 
35*ccae43a2SGeorge Burgess IV   // 100 is arbitrary.
36*ccae43a2SGeorge Burgess IV   std::unique_ptr<CallInst> Caller(
37*ccae43a2SGeorge Burgess IV       CallInst::Create(AllocSizeFn, {ConstantInt::get(ArgTy, 100)}));
38*ccae43a2SGeorge Burgess IV 
39*ccae43a2SGeorge Burgess IV   const TargetLibraryInfo *TLI = nullptr;
40*ccae43a2SGeorge Burgess IV   EXPECT_FALSE(isNoAliasFn(Caller.get(), TLI));
41*ccae43a2SGeorge Burgess IV   EXPECT_FALSE(isMallocLikeFn(Caller.get(), TLI));
42*ccae43a2SGeorge Burgess IV   EXPECT_FALSE(isCallocLikeFn(Caller.get(), TLI));
43*ccae43a2SGeorge Burgess IV   EXPECT_FALSE(isAllocLikeFn(Caller.get(), TLI));
44*ccae43a2SGeorge Burgess IV 
45*ccae43a2SGeorge Burgess IV   // FIXME: We might be able to treat allocsize functions as general allocation
46*ccae43a2SGeorge Burgess IV   // functions. For the moment, being conservative seems better (and we'd have
47*ccae43a2SGeorge Burgess IV   // to plumb stuff around `isNoAliasFn`).
48*ccae43a2SGeorge Burgess IV   EXPECT_FALSE(isAllocationFn(Caller.get(), TLI));
49*ccae43a2SGeorge Burgess IV }
50*ccae43a2SGeorge Burgess IV }
51