teach objectsize about strdup() and strndup()

llvm-svn: 160676
This commit is contained in:
Nuno Lopes 2012-07-24 16:28:13 +00:00
parent 1c85d5b17d
commit 2a4b09c9de
2 changed files with 64 additions and 3 deletions

View File

@ -64,7 +64,7 @@ static const AllocFnsTy AllocationFnData[] = {
{"realloc", ReallocLike, 2, 1, -1},
{"reallocf", ReallocLike, 2, 1, -1},
{"strdup", StrDupLike, 1, -1, -1},
{"strndup", StrDupLike, 2, -1, -1}
{"strndup", StrDupLike, 2, 1, -1}
};
@ -414,8 +414,21 @@ SizeOffsetType ObjectSizeOffsetVisitor::visitCallSite(CallSite CS) {
// handle strdup-like functions separately
if (FnData->AllocTy == StrDupLike) {
// TODO
return unknown();
APInt Size(IntTyBits, GetStringLength(CS.getArgument(0)));
if (!Size)
return unknown();
// strndup limits strlen
if (FnData->FstParam > 0) {
ConstantInt *Arg= dyn_cast<ConstantInt>(CS.getArgument(FnData->FstParam));
if (!Arg)
return unknown();
APInt MaxSize = Arg->getValue().zextOrSelf(IntTyBits);
if (Size.ugt(MaxSize))
Size = MaxSize + 1;
}
return std::make_pair(Size, Zero);
}
ConstantInt *Arg = dyn_cast<ConstantInt>(CS.getArgument(FnData->FstParam));

View File

@ -171,3 +171,51 @@ define i32 @test8(i8** %esc) {
; CHECK: ret i32 30
ret i32 %objsize
}
declare noalias i8* @strdup(i8* nocapture) nounwind
declare noalias i8* @strndup(i8* nocapture, i32) nounwind
; CHECK: @test9
define i32 @test9(i8** %esc) {
%call = tail call i8* @strdup(i8* getelementptr inbounds ([8 x i8]* @.str, i64 0, i64 0)) nounwind
store i8* %call, i8** %esc, align 8
%1 = tail call i32 @llvm.objectsize.i32(i8* %call, i1 true)
; CHECK: ret i32 8
ret i32 %1
}
; CHECK: @test10
define i32 @test10(i8** %esc) {
%call = tail call i8* @strndup(i8* getelementptr inbounds ([8 x i8]* @.str, i64 0, i64 0), i32 3) nounwind
store i8* %call, i8** %esc, align 8
%1 = tail call i32 @llvm.objectsize.i32(i8* %call, i1 true)
; CHECK: ret i32 4
ret i32 %1
}
; CHECK: @test11
define i32 @test11(i8** %esc) {
%call = tail call i8* @strndup(i8* getelementptr inbounds ([8 x i8]* @.str, i64 0, i64 0), i32 7) nounwind
store i8* %call, i8** %esc, align 8
%1 = tail call i32 @llvm.objectsize.i32(i8* %call, i1 true)
; CHECK: ret i32 8
ret i32 %1
}
; CHECK: @test12
define i32 @test12(i8** %esc) {
%call = tail call i8* @strndup(i8* getelementptr inbounds ([8 x i8]* @.str, i64 0, i64 0), i32 8) nounwind
store i8* %call, i8** %esc, align 8
%1 = tail call i32 @llvm.objectsize.i32(i8* %call, i1 true)
; CHECK: ret i32 8
ret i32 %1
}
; CHECK: @test13
define i32 @test13(i8** %esc) {
%call = tail call i8* @strndup(i8* getelementptr inbounds ([8 x i8]* @.str, i64 0, i64 0), i32 57) nounwind
store i8* %call, i8** %esc, align 8
%1 = tail call i32 @llvm.objectsize.i32(i8* %call, i1 true)
; CHECK: ret i32 8
ret i32 %1
}