[SimplifyLibCalls] sprintf doesn't copy null bytes

sprintf doesn't read or copy the terminating null byte from it's string
operands.  sprintf will append it's own after processing all of the
format specifiers.

This fixes PR27526.

llvm-svn: 267580
This commit is contained in:
David Majnemer 2016-04-26 18:16:49 +00:00
parent 1c3f65a18c
commit 8cd77baebc
2 changed files with 7 additions and 5 deletions

View File

@ -1995,9 +1995,10 @@ Value *LibCallSimplifier::optimizeSPrintFString(CallInst *CI, IRBuilder<> &B) {
Value *Len = emitStrLen(CI->getArgOperand(2), B, DL, TLI);
if (!Len)
return nullptr;
Value *IncLen =
B.CreateAdd(Len, ConstantInt::get(Len->getType(), 1), "leninc");
B.CreateMemCpy(CI->getArgOperand(0), CI->getArgOperand(2), IncLen, 1);
B.CreateMemCpy(CI->getArgOperand(0), CI->getArgOperand(2), Len, 1);
Value *PtrToNullByte =
B.CreateGEP(B.getInt8Ty(), CI->getArgOperand(0), Len, "nul");
B.CreateStore(B.getInt8(0), PtrToNullByte);
// The sprintf result is the unincremented number of bytes in the string.
return B.CreateIntCast(Len, CI->getType(), false);

View File

@ -65,8 +65,9 @@ define void @test_simplify5(i8* %dst, i8* %str) {
%fmt = getelementptr [3 x i8], [3 x i8]* @percent_s, i32 0, i32 0
call i32 (i8*, i8*, ...) @sprintf(i8* %dst, i8* %fmt, i8* %str)
; CHECK-NEXT: [[STRLEN:%[a-z0-9]+]] = call i32 @strlen(i8* %str)
; CHECK-NEXT: [[LENINC:%[a-z0-9]+]] = add i32 [[STRLEN]], 1
; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dst, i8* %str, i32 [[LENINC]], i32 1, i1 false)
; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dst, i8* %str, i32 [[STRLEN]], i32 1, i1 false)
; CHECK-NEXT: [[NUL:%[a-z0-9]+]] = getelementptr i8, i8* %dst, i32 [[STRLEN]]
; CHECK-NEXT: store i8 0, i8* [[NUL]], align 1
ret void
; CHECK-NEXT: ret void
}