1//===- BuildLibCalls.cpp - Utility builder for libcalls -------------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements some functions that will create standard C libcalls.
11//
12//===----------------------------------------------------------------------===//
13
14#include "llvm/Transforms/Utils/BuildLibCalls.h"
15#include "llvm/Constants.h"
16#include "llvm/Function.h"
17#include "llvm/IRBuilder.h"
18#include "llvm/Intrinsics.h"
19#include "llvm/Intrinsics.h"
20#include "llvm/LLVMContext.h"
21#include "llvm/LLVMContext.h"
22#include "llvm/Module.h"
23#include "llvm/Type.h"
24#include "llvm/ADT/SmallString.h"
25#include "llvm/Target/TargetData.h"
26#include "llvm/Target/TargetLibraryInfo.h"
27
28using namespace llvm;
29
30/// CastToCStr - Return V if it is an i8*, otherwise cast it to i8*.
31Value *llvm::CastToCStr(Value *V, IRBuilder<> &B) {
32  return B.CreateBitCast(V, B.getInt8PtrTy(), "cstr");
33}
34
35/// EmitStrLen - Emit a call to the strlen function to the builder, for the
36/// specified pointer.  This always returns an integer value of size intptr_t.
37Value *llvm::EmitStrLen(Value *Ptr, IRBuilder<> &B, const TargetData *TD,
38                        const TargetLibraryInfo *TLI) {
39  if (!TLI->has(LibFunc::strlen))
40    return 0;
41
42  Module *M = B.GetInsertBlock()->getParent()->getParent();
43  AttributeWithIndex AWI[2];
44  AWI[0] = AttributeWithIndex::get(1, Attribute::NoCapture);
45  AWI[1] = AttributeWithIndex::get(~0u, Attribute::ReadOnly |
46                                   Attribute::NoUnwind);
47
48  LLVMContext &Context = B.GetInsertBlock()->getContext();
49  Constant *StrLen = M->getOrInsertFunction("strlen", AttrListPtr::get(AWI),
50                                            TD->getIntPtrType(Context),
51                                            B.getInt8PtrTy(),
52                                            NULL);
53  CallInst *CI = B.CreateCall(StrLen, CastToCStr(Ptr, B), "strlen");
54  if (const Function *F = dyn_cast<Function>(StrLen->stripPointerCasts()))
55    CI->setCallingConv(F->getCallingConv());
56
57  return CI;
58}
59
60/// EmitStrNLen - Emit a call to the strnlen function to the builder, for the
61/// specified pointer.  Ptr is required to be some pointer type, MaxLen must
62/// be of size_t type, and the return value has 'intptr_t' type.
63Value *llvm::EmitStrNLen(Value *Ptr, Value *MaxLen, IRBuilder<> &B,
64                         const TargetData *TD, const TargetLibraryInfo *TLI) {
65  if (!TLI->has(LibFunc::strnlen))
66    return 0;
67
68  Module *M = B.GetInsertBlock()->getParent()->getParent();
69  AttributeWithIndex AWI[2];
70  AWI[0] = AttributeWithIndex::get(1, Attribute::NoCapture);
71  AWI[1] = AttributeWithIndex::get(~0u, Attribute::ReadOnly |
72                                   Attribute::NoUnwind);
73
74  LLVMContext &Context = B.GetInsertBlock()->getContext();
75  Constant *StrNLen = M->getOrInsertFunction("strnlen", AttrListPtr::get(AWI),
76                                             TD->getIntPtrType(Context),
77                                             B.getInt8PtrTy(),
78                                             TD->getIntPtrType(Context),
79                                             NULL);
80  CallInst *CI = B.CreateCall2(StrNLen, CastToCStr(Ptr, B), MaxLen, "strnlen");
81  if (const Function *F = dyn_cast<Function>(StrNLen->stripPointerCasts()))
82    CI->setCallingConv(F->getCallingConv());
83
84  return CI;
85}
86
87/// EmitStrChr - Emit a call to the strchr function to the builder, for the
88/// specified pointer and character.  Ptr is required to be some pointer type,
89/// and the return value has 'i8*' type.
90Value *llvm::EmitStrChr(Value *Ptr, char C, IRBuilder<> &B,
91                        const TargetData *TD, const TargetLibraryInfo *TLI) {
92  if (!TLI->has(LibFunc::strchr))
93    return 0;
94
95  Module *M = B.GetInsertBlock()->getParent()->getParent();
96  AttributeWithIndex AWI =
97    AttributeWithIndex::get(~0u, Attribute::ReadOnly | Attribute::NoUnwind);
98
99  Type *I8Ptr = B.getInt8PtrTy();
100  Type *I32Ty = B.getInt32Ty();
101  Constant *StrChr = M->getOrInsertFunction("strchr", AttrListPtr::get(AWI),
102                                            I8Ptr, I8Ptr, I32Ty, NULL);
103  CallInst *CI = B.CreateCall2(StrChr, CastToCStr(Ptr, B),
104                               ConstantInt::get(I32Ty, C), "strchr");
105  if (const Function *F = dyn_cast<Function>(StrChr->stripPointerCasts()))
106    CI->setCallingConv(F->getCallingConv());
107  return CI;
108}
109
110/// EmitStrNCmp - Emit a call to the strncmp function to the builder.
111Value *llvm::EmitStrNCmp(Value *Ptr1, Value *Ptr2, Value *Len,
112                         IRBuilder<> &B, const TargetData *TD,
113                         const TargetLibraryInfo *TLI) {
114  if (!TLI->has(LibFunc::strncmp))
115    return 0;
116
117  Module *M = B.GetInsertBlock()->getParent()->getParent();
118  AttributeWithIndex AWI[3];
119  AWI[0] = AttributeWithIndex::get(1, Attribute::NoCapture);
120  AWI[1] = AttributeWithIndex::get(2, Attribute::NoCapture);
121  AWI[2] = AttributeWithIndex::get(~0u, Attribute::ReadOnly |
122                                   Attribute::NoUnwind);
123
124  LLVMContext &Context = B.GetInsertBlock()->getContext();
125  Value *StrNCmp = M->getOrInsertFunction("strncmp", AttrListPtr::get(AWI),
126                                          B.getInt32Ty(),
127                                          B.getInt8PtrTy(),
128                                          B.getInt8PtrTy(),
129                                          TD->getIntPtrType(Context), NULL);
130  CallInst *CI = B.CreateCall3(StrNCmp, CastToCStr(Ptr1, B),
131                               CastToCStr(Ptr2, B), Len, "strncmp");
132
133  if (const Function *F = dyn_cast<Function>(StrNCmp->stripPointerCasts()))
134    CI->setCallingConv(F->getCallingConv());
135
136  return CI;
137}
138
139/// EmitStrCpy - Emit a call to the strcpy function to the builder, for the
140/// specified pointer arguments.
141Value *llvm::EmitStrCpy(Value *Dst, Value *Src, IRBuilder<> &B,
142                        const TargetData *TD, const TargetLibraryInfo *TLI,
143                        StringRef Name) {
144  if (!TLI->has(LibFunc::strcpy))
145    return 0;
146
147  Module *M = B.GetInsertBlock()->getParent()->getParent();
148  AttributeWithIndex AWI[2];
149  AWI[0] = AttributeWithIndex::get(2, Attribute::NoCapture);
150  AWI[1] = AttributeWithIndex::get(~0u, Attribute::NoUnwind);
151  Type *I8Ptr = B.getInt8PtrTy();
152  Value *StrCpy = M->getOrInsertFunction(Name, AttrListPtr::get(AWI),
153                                         I8Ptr, I8Ptr, I8Ptr, NULL);
154  CallInst *CI = B.CreateCall2(StrCpy, CastToCStr(Dst, B), CastToCStr(Src, B),
155                               Name);
156  if (const Function *F = dyn_cast<Function>(StrCpy->stripPointerCasts()))
157    CI->setCallingConv(F->getCallingConv());
158  return CI;
159}
160
161/// EmitStrNCpy - Emit a call to the strncpy function to the builder, for the
162/// specified pointer arguments.
163Value *llvm::EmitStrNCpy(Value *Dst, Value *Src, Value *Len,
164                         IRBuilder<> &B, const TargetData *TD,
165                         const TargetLibraryInfo *TLI, StringRef Name) {
166  if (!TLI->has(LibFunc::strncpy))
167    return 0;
168
169  Module *M = B.GetInsertBlock()->getParent()->getParent();
170  AttributeWithIndex AWI[2];
171  AWI[0] = AttributeWithIndex::get(2, Attribute::NoCapture);
172  AWI[1] = AttributeWithIndex::get(~0u, Attribute::NoUnwind);
173  Type *I8Ptr = B.getInt8PtrTy();
174  Value *StrNCpy = M->getOrInsertFunction(Name, AttrListPtr::get(AWI),
175                                          I8Ptr, I8Ptr, I8Ptr,
176                                          Len->getType(), NULL);
177  CallInst *CI = B.CreateCall3(StrNCpy, CastToCStr(Dst, B), CastToCStr(Src, B),
178                               Len, "strncpy");
179  if (const Function *F = dyn_cast<Function>(StrNCpy->stripPointerCasts()))
180    CI->setCallingConv(F->getCallingConv());
181  return CI;
182}
183
184/// EmitMemCpyChk - Emit a call to the __memcpy_chk function to the builder.
185/// This expects that the Len and ObjSize have type 'intptr_t' and Dst/Src
186/// are pointers.
187Value *llvm::EmitMemCpyChk(Value *Dst, Value *Src, Value *Len, Value *ObjSize,
188                           IRBuilder<> &B, const TargetData *TD,
189                           const TargetLibraryInfo *TLI) {
190  if (!TLI->has(LibFunc::memcpy_chk))
191    return 0;
192
193  Module *M = B.GetInsertBlock()->getParent()->getParent();
194  AttributeWithIndex AWI;
195  AWI = AttributeWithIndex::get(~0u, Attribute::NoUnwind);
196  LLVMContext &Context = B.GetInsertBlock()->getContext();
197  Value *MemCpy = M->getOrInsertFunction("__memcpy_chk",
198                                         AttrListPtr::get(AWI),
199                                         B.getInt8PtrTy(),
200                                         B.getInt8PtrTy(),
201                                         B.getInt8PtrTy(),
202                                         TD->getIntPtrType(Context),
203                                         TD->getIntPtrType(Context), NULL);
204  Dst = CastToCStr(Dst, B);
205  Src = CastToCStr(Src, B);
206  CallInst *CI = B.CreateCall4(MemCpy, Dst, Src, Len, ObjSize);
207  if (const Function *F = dyn_cast<Function>(MemCpy->stripPointerCasts()))
208    CI->setCallingConv(F->getCallingConv());
209  return CI;
210}
211
212/// EmitMemChr - Emit a call to the memchr function.  This assumes that Ptr is
213/// a pointer, Val is an i32 value, and Len is an 'intptr_t' value.
214Value *llvm::EmitMemChr(Value *Ptr, Value *Val,
215                        Value *Len, IRBuilder<> &B, const TargetData *TD,
216                        const TargetLibraryInfo *TLI) {
217  if (!TLI->has(LibFunc::memchr))
218    return 0;
219
220  Module *M = B.GetInsertBlock()->getParent()->getParent();
221  AttributeWithIndex AWI;
222  AWI = AttributeWithIndex::get(~0u, Attribute::ReadOnly | Attribute::NoUnwind);
223  LLVMContext &Context = B.GetInsertBlock()->getContext();
224  Value *MemChr = M->getOrInsertFunction("memchr", AttrListPtr::get(AWI),
225                                         B.getInt8PtrTy(),
226                                         B.getInt8PtrTy(),
227                                         B.getInt32Ty(),
228                                         TD->getIntPtrType(Context),
229                                         NULL);
230  CallInst *CI = B.CreateCall3(MemChr, CastToCStr(Ptr, B), Val, Len, "memchr");
231
232  if (const Function *F = dyn_cast<Function>(MemChr->stripPointerCasts()))
233    CI->setCallingConv(F->getCallingConv());
234
235  return CI;
236}
237
238/// EmitMemCmp - Emit a call to the memcmp function.
239Value *llvm::EmitMemCmp(Value *Ptr1, Value *Ptr2,
240                        Value *Len, IRBuilder<> &B, const TargetData *TD,
241                        const TargetLibraryInfo *TLI) {
242  if (!TLI->has(LibFunc::memcmp))
243    return 0;
244
245  Module *M = B.GetInsertBlock()->getParent()->getParent();
246  AttributeWithIndex AWI[3];
247  AWI[0] = AttributeWithIndex::get(1, Attribute::NoCapture);
248  AWI[1] = AttributeWithIndex::get(2, Attribute::NoCapture);
249  AWI[2] = AttributeWithIndex::get(~0u, Attribute::ReadOnly |
250                                   Attribute::NoUnwind);
251
252  LLVMContext &Context = B.GetInsertBlock()->getContext();
253  Value *MemCmp = M->getOrInsertFunction("memcmp", AttrListPtr::get(AWI),
254                                         B.getInt32Ty(),
255                                         B.getInt8PtrTy(),
256                                         B.getInt8PtrTy(),
257                                         TD->getIntPtrType(Context), NULL);
258  CallInst *CI = B.CreateCall3(MemCmp, CastToCStr(Ptr1, B), CastToCStr(Ptr2, B),
259                               Len, "memcmp");
260
261  if (const Function *F = dyn_cast<Function>(MemCmp->stripPointerCasts()))
262    CI->setCallingConv(F->getCallingConv());
263
264  return CI;
265}
266
267/// EmitUnaryFloatFnCall - Emit a call to the unary function named 'Name' (e.g.
268/// 'floor').  This function is known to take a single of type matching 'Op' and
269/// returns one value with the same type.  If 'Op' is a long double, 'l' is
270/// added as the suffix of name, if 'Op' is a float, we add a 'f' suffix.
271Value *llvm::EmitUnaryFloatFnCall(Value *Op, StringRef Name, IRBuilder<> &B,
272                                  const AttrListPtr &Attrs) {
273  SmallString<20> NameBuffer;
274  if (!Op->getType()->isDoubleTy()) {
275    // If we need to add a suffix, copy into NameBuffer.
276    NameBuffer += Name;
277    if (Op->getType()->isFloatTy())
278      NameBuffer += 'f'; // floorf
279    else
280      NameBuffer += 'l'; // floorl
281    Name = NameBuffer;
282  }
283
284  Module *M = B.GetInsertBlock()->getParent()->getParent();
285  Value *Callee = M->getOrInsertFunction(Name, Op->getType(),
286                                         Op->getType(), NULL);
287  CallInst *CI = B.CreateCall(Callee, Op, Name);
288  CI->setAttributes(Attrs);
289  if (const Function *F = dyn_cast<Function>(Callee->stripPointerCasts()))
290    CI->setCallingConv(F->getCallingConv());
291
292  return CI;
293}
294
295/// EmitPutChar - Emit a call to the putchar function.  This assumes that Char
296/// is an integer.
297Value *llvm::EmitPutChar(Value *Char, IRBuilder<> &B, const TargetData *TD,
298                         const TargetLibraryInfo *TLI) {
299  if (!TLI->has(LibFunc::putchar))
300    return 0;
301
302  Module *M = B.GetInsertBlock()->getParent()->getParent();
303  Value *PutChar = M->getOrInsertFunction("putchar", B.getInt32Ty(),
304                                          B.getInt32Ty(), NULL);
305  CallInst *CI = B.CreateCall(PutChar,
306                              B.CreateIntCast(Char,
307                              B.getInt32Ty(),
308                              /*isSigned*/true,
309                              "chari"),
310                              "putchar");
311
312  if (const Function *F = dyn_cast<Function>(PutChar->stripPointerCasts()))
313    CI->setCallingConv(F->getCallingConv());
314  return CI;
315}
316
317/// EmitPutS - Emit a call to the puts function.  This assumes that Str is
318/// some pointer.
319Value *llvm::EmitPutS(Value *Str, IRBuilder<> &B, const TargetData *TD,
320                      const TargetLibraryInfo *TLI) {
321  if (!TLI->has(LibFunc::puts))
322    return 0;
323
324  Module *M = B.GetInsertBlock()->getParent()->getParent();
325  AttributeWithIndex AWI[2];
326  AWI[0] = AttributeWithIndex::get(1, Attribute::NoCapture);
327  AWI[1] = AttributeWithIndex::get(~0u, Attribute::NoUnwind);
328
329  Value *PutS = M->getOrInsertFunction("puts", AttrListPtr::get(AWI),
330                                       B.getInt32Ty(),
331                                       B.getInt8PtrTy(),
332                                       NULL);
333  CallInst *CI = B.CreateCall(PutS, CastToCStr(Str, B), "puts");
334  if (const Function *F = dyn_cast<Function>(PutS->stripPointerCasts()))
335    CI->setCallingConv(F->getCallingConv());
336  return CI;
337}
338
339/// EmitFPutC - Emit a call to the fputc function.  This assumes that Char is
340/// an integer and File is a pointer to FILE.
341Value *llvm::EmitFPutC(Value *Char, Value *File, IRBuilder<> &B,
342                       const TargetData *TD, const TargetLibraryInfo *TLI) {
343  if (!TLI->has(LibFunc::fputc))
344    return 0;
345
346  Module *M = B.GetInsertBlock()->getParent()->getParent();
347  AttributeWithIndex AWI[2];
348  AWI[0] = AttributeWithIndex::get(2, Attribute::NoCapture);
349  AWI[1] = AttributeWithIndex::get(~0u, Attribute::NoUnwind);
350  Constant *F;
351  if (File->getType()->isPointerTy())
352    F = M->getOrInsertFunction("fputc", AttrListPtr::get(AWI),
353                               B.getInt32Ty(),
354                               B.getInt32Ty(), File->getType(),
355                               NULL);
356  else
357    F = M->getOrInsertFunction("fputc",
358                               B.getInt32Ty(),
359                               B.getInt32Ty(),
360                               File->getType(), NULL);
361  Char = B.CreateIntCast(Char, B.getInt32Ty(), /*isSigned*/true,
362                         "chari");
363  CallInst *CI = B.CreateCall2(F, Char, File, "fputc");
364
365  if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
366    CI->setCallingConv(Fn->getCallingConv());
367  return CI;
368}
369
370/// EmitFPutS - Emit a call to the puts function.  Str is required to be a
371/// pointer and File is a pointer to FILE.
372Value *llvm::EmitFPutS(Value *Str, Value *File, IRBuilder<> &B,
373                       const TargetData *TD, const TargetLibraryInfo *TLI) {
374  if (!TLI->has(LibFunc::fputs))
375    return 0;
376
377  Module *M = B.GetInsertBlock()->getParent()->getParent();
378  AttributeWithIndex AWI[3];
379  AWI[0] = AttributeWithIndex::get(1, Attribute::NoCapture);
380  AWI[1] = AttributeWithIndex::get(2, Attribute::NoCapture);
381  AWI[2] = AttributeWithIndex::get(~0u, Attribute::NoUnwind);
382  StringRef FPutsName = TLI->getName(LibFunc::fputs);
383  Constant *F;
384  if (File->getType()->isPointerTy())
385    F = M->getOrInsertFunction(FPutsName, AttrListPtr::get(AWI),
386                               B.getInt32Ty(),
387                               B.getInt8PtrTy(),
388                               File->getType(), NULL);
389  else
390    F = M->getOrInsertFunction(FPutsName, B.getInt32Ty(),
391                               B.getInt8PtrTy(),
392                               File->getType(), NULL);
393  CallInst *CI = B.CreateCall2(F, CastToCStr(Str, B), File, "fputs");
394
395  if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
396    CI->setCallingConv(Fn->getCallingConv());
397  return CI;
398}
399
400/// EmitFWrite - Emit a call to the fwrite function.  This assumes that Ptr is
401/// a pointer, Size is an 'intptr_t', and File is a pointer to FILE.
402Value *llvm::EmitFWrite(Value *Ptr, Value *Size, Value *File,
403                        IRBuilder<> &B, const TargetData *TD,
404                        const TargetLibraryInfo *TLI) {
405  if (!TLI->has(LibFunc::fwrite))
406    return 0;
407
408  Module *M = B.GetInsertBlock()->getParent()->getParent();
409  AttributeWithIndex AWI[3];
410  AWI[0] = AttributeWithIndex::get(1, Attribute::NoCapture);
411  AWI[1] = AttributeWithIndex::get(4, Attribute::NoCapture);
412  AWI[2] = AttributeWithIndex::get(~0u, Attribute::NoUnwind);
413  LLVMContext &Context = B.GetInsertBlock()->getContext();
414  StringRef FWriteName = TLI->getName(LibFunc::fwrite);
415  Constant *F;
416  if (File->getType()->isPointerTy())
417    F = M->getOrInsertFunction(FWriteName, AttrListPtr::get(AWI),
418                               TD->getIntPtrType(Context),
419                               B.getInt8PtrTy(),
420                               TD->getIntPtrType(Context),
421                               TD->getIntPtrType(Context),
422                               File->getType(), NULL);
423  else
424    F = M->getOrInsertFunction(FWriteName, TD->getIntPtrType(Context),
425                               B.getInt8PtrTy(),
426                               TD->getIntPtrType(Context),
427                               TD->getIntPtrType(Context),
428                               File->getType(), NULL);
429  CallInst *CI = B.CreateCall4(F, CastToCStr(Ptr, B), Size,
430                        ConstantInt::get(TD->getIntPtrType(Context), 1), File);
431
432  if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
433    CI->setCallingConv(Fn->getCallingConv());
434  return CI;
435}
436
437SimplifyFortifiedLibCalls::~SimplifyFortifiedLibCalls() { }
438
439bool SimplifyFortifiedLibCalls::fold(CallInst *CI, const TargetData *TD,
440                                     const TargetLibraryInfo *TLI) {
441  // We really need TargetData for later.
442  if (!TD) return false;
443
444  this->CI = CI;
445  Function *Callee = CI->getCalledFunction();
446  StringRef Name = Callee->getName();
447  FunctionType *FT = Callee->getFunctionType();
448  LLVMContext &Context = CI->getParent()->getContext();
449  IRBuilder<> B(CI);
450
451  if (Name == "__memcpy_chk") {
452    // Check if this has the right signature.
453    if (FT->getNumParams() != 4 || FT->getReturnType() != FT->getParamType(0) ||
454        !FT->getParamType(0)->isPointerTy() ||
455        !FT->getParamType(1)->isPointerTy() ||
456        FT->getParamType(2) != TD->getIntPtrType(Context) ||
457        FT->getParamType(3) != TD->getIntPtrType(Context))
458      return false;
459
460    if (isFoldable(3, 2, false)) {
461      B.CreateMemCpy(CI->getArgOperand(0), CI->getArgOperand(1),
462                     CI->getArgOperand(2), 1);
463      replaceCall(CI->getArgOperand(0));
464      return true;
465    }
466    return false;
467  }
468
469  // Should be similar to memcpy.
470  if (Name == "__mempcpy_chk") {
471    return false;
472  }
473
474  if (Name == "__memmove_chk") {
475    // Check if this has the right signature.
476    if (FT->getNumParams() != 4 || FT->getReturnType() != FT->getParamType(0) ||
477        !FT->getParamType(0)->isPointerTy() ||
478        !FT->getParamType(1)->isPointerTy() ||
479        FT->getParamType(2) != TD->getIntPtrType(Context) ||
480        FT->getParamType(3) != TD->getIntPtrType(Context))
481      return false;
482
483    if (isFoldable(3, 2, false)) {
484      B.CreateMemMove(CI->getArgOperand(0), CI->getArgOperand(1),
485                      CI->getArgOperand(2), 1);
486      replaceCall(CI->getArgOperand(0));
487      return true;
488    }
489    return false;
490  }
491
492  if (Name == "__memset_chk") {
493    // Check if this has the right signature.
494    if (FT->getNumParams() != 4 || FT->getReturnType() != FT->getParamType(0) ||
495        !FT->getParamType(0)->isPointerTy() ||
496        !FT->getParamType(1)->isIntegerTy() ||
497        FT->getParamType(2) != TD->getIntPtrType(Context) ||
498        FT->getParamType(3) != TD->getIntPtrType(Context))
499      return false;
500
501    if (isFoldable(3, 2, false)) {
502      Value *Val = B.CreateIntCast(CI->getArgOperand(1), B.getInt8Ty(),
503                                   false);
504      B.CreateMemSet(CI->getArgOperand(0), Val, CI->getArgOperand(2), 1);
505      replaceCall(CI->getArgOperand(0));
506      return true;
507    }
508    return false;
509  }
510
511  if (Name == "__strcpy_chk" || Name == "__stpcpy_chk") {
512    // Check if this has the right signature.
513    if (FT->getNumParams() != 3 ||
514        FT->getReturnType() != FT->getParamType(0) ||
515        FT->getParamType(0) != FT->getParamType(1) ||
516        FT->getParamType(0) != Type::getInt8PtrTy(Context) ||
517        FT->getParamType(2) != TD->getIntPtrType(Context))
518      return 0;
519
520
521    // If a) we don't have any length information, or b) we know this will
522    // fit then just lower to a plain st[rp]cpy. Otherwise we'll keep our
523    // st[rp]cpy_chk call which may fail at runtime if the size is too long.
524    // TODO: It might be nice to get a maximum length out of the possible
525    // string lengths for varying.
526    if (isFoldable(2, 1, true)) {
527      Value *Ret = EmitStrCpy(CI->getArgOperand(0), CI->getArgOperand(1), B, TD,
528                              TLI, Name.substr(2, 6));
529      if (!Ret)
530        return false;
531      replaceCall(Ret);
532      return true;
533    }
534    return false;
535  }
536
537  if (Name == "__strncpy_chk" || Name == "__stpncpy_chk") {
538    // Check if this has the right signature.
539    if (FT->getNumParams() != 4 || FT->getReturnType() != FT->getParamType(0) ||
540        FT->getParamType(0) != FT->getParamType(1) ||
541        FT->getParamType(0) != Type::getInt8PtrTy(Context) ||
542        !FT->getParamType(2)->isIntegerTy() ||
543        FT->getParamType(3) != TD->getIntPtrType(Context))
544      return false;
545
546    if (isFoldable(3, 2, false)) {
547      Value *Ret = EmitStrNCpy(CI->getArgOperand(0), CI->getArgOperand(1),
548                               CI->getArgOperand(2), B, TD, TLI,
549                               Name.substr(2, 7));
550      if (!Ret)
551        return false;
552      replaceCall(Ret);
553      return true;
554    }
555    return false;
556  }
557
558  if (Name == "__strcat_chk") {
559    return false;
560  }
561
562  if (Name == "__strncat_chk") {
563    return false;
564  }
565
566  return false;
567}
568