forked from OSchip/llvm-project
[InstCombine] Annotate strndup calls with dereferenceable_or_null
"Implementations are free to malloc() a buffer containing either (size + 1) bytes or (strnlen(s, size) + 1) bytes. Applications should not assume that strndup() will allocate (size + 1) bytes when strlen(s) is smaller than size." llvm-svn: 372647
This commit is contained in:
parent
174d43d123
commit
48db0272d6
|
@ -4179,10 +4179,10 @@ static IntrinsicInst *findInitTrampoline(Value *Callee) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void annotateAnyAllocSite(CallBase &Call, const TargetLibraryInfo *TLI) {
|
static void annotateAnyAllocSite(CallBase &Call, const TargetLibraryInfo *TLI) {
|
||||||
|
unsigned NumArgs = Call.getNumArgOperands();
|
||||||
ConstantInt *Op0C = dyn_cast<ConstantInt>(Call.getOperand(0));
|
ConstantInt *Op0C = dyn_cast<ConstantInt>(Call.getOperand(0));
|
||||||
ConstantInt *Op1C = (Call.getNumArgOperands() == 1)
|
ConstantInt *Op1C =
|
||||||
? nullptr
|
(NumArgs == 1) ? nullptr : dyn_cast<ConstantInt>(Call.getOperand(1));
|
||||||
: dyn_cast<ConstantInt>(Call.getOperand(1));
|
|
||||||
// Bail out if the allocation size is zero.
|
// Bail out if the allocation size is zero.
|
||||||
if ((Op0C && Op0C->isNullValue()) || (Op1C && Op1C->isNullValue()))
|
if ((Op0C && Op0C->isNullValue()) || (Op1C && Op1C->isNullValue()))
|
||||||
return;
|
return;
|
||||||
|
@ -4208,12 +4208,21 @@ static void annotateAnyAllocSite(CallBase &Call, const TargetLibraryInfo *TLI) {
|
||||||
Call.addAttribute(AttributeList::ReturnIndex,
|
Call.addAttribute(AttributeList::ReturnIndex,
|
||||||
Attribute::getWithDereferenceableOrNullBytes(
|
Attribute::getWithDereferenceableOrNullBytes(
|
||||||
Call.getContext(), Size.getZExtValue()));
|
Call.getContext(), Size.getZExtValue()));
|
||||||
} else if (isStrdupLikeFn(&Call, TLI) && Call.getNumArgOperands() == 1) {
|
} else if (isStrdupLikeFn(&Call, TLI)) {
|
||||||
// TODO: handle strndup
|
uint64_t Len = GetStringLength(Call.getOperand(0));
|
||||||
if (uint64_t Len = GetStringLength(Call.getOperand(0)))
|
if (Len) {
|
||||||
Call.addAttribute(
|
// strdup
|
||||||
AttributeList::ReturnIndex,
|
if (NumArgs == 1)
|
||||||
Attribute::getWithDereferenceableOrNullBytes(Call.getContext(), Len));
|
Call.addAttribute(AttributeList::ReturnIndex,
|
||||||
|
Attribute::getWithDereferenceableOrNullBytes(
|
||||||
|
Call.getContext(), Len));
|
||||||
|
// strndup
|
||||||
|
else if (NumArgs == 2 && Op1C)
|
||||||
|
Call.addAttribute(
|
||||||
|
AttributeList::ReturnIndex,
|
||||||
|
Attribute::getWithDereferenceableOrNullBytes(
|
||||||
|
Call.getContext(), std::min(Len, Op1C->getZExtValue() + 1)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -239,7 +239,7 @@ define i32 @test9(i8** %esc) {
|
||||||
|
|
||||||
define i32 @test10(i8** %esc) {
|
define i32 @test10(i8** %esc) {
|
||||||
; CHECK-LABEL: @test10(
|
; CHECK-LABEL: @test10(
|
||||||
; CHECK-NEXT: [[CALL:%.*]] = tail call i8* @strndup(i8* dereferenceable(8) getelementptr inbounds ([8 x i8], [8 x i8]* @.str, i32 0, i32 0), i32 3) #0
|
; CHECK-NEXT: [[CALL:%.*]] = tail call dereferenceable_or_null(4) i8* @strndup(i8* dereferenceable(8) getelementptr inbounds ([8 x i8], [8 x i8]* @.str, i32 0, i32 0), i32 3) #0
|
||||||
; CHECK-NEXT: store i8* [[CALL]], i8** [[ESC:%.*]], align 8
|
; CHECK-NEXT: store i8* [[CALL]], i8** [[ESC:%.*]], align 8
|
||||||
; CHECK-NEXT: ret i32 4
|
; CHECK-NEXT: ret i32 4
|
||||||
;
|
;
|
||||||
|
|
|
@ -18,7 +18,7 @@ define i8* @test1() {
|
||||||
|
|
||||||
define i8* @test2() {
|
define i8* @test2() {
|
||||||
; CHECK-LABEL: @test2(
|
; CHECK-LABEL: @test2(
|
||||||
; CHECK-NEXT: [[RET:%.*]] = call i8* @strndup(i8* dereferenceable(6) getelementptr inbounds ([6 x i8], [6 x i8]* @hello, i64 0, i64 0), i32 4)
|
; CHECK-NEXT: [[RET:%.*]] = call dereferenceable_or_null(5) i8* @strndup(i8* dereferenceable(6) getelementptr inbounds ([6 x i8], [6 x i8]* @hello, i64 0, i64 0), i32 4)
|
||||||
; CHECK-NEXT: ret i8* [[RET]]
|
; CHECK-NEXT: ret i8* [[RET]]
|
||||||
;
|
;
|
||||||
%src = getelementptr [6 x i8], [6 x i8]* @hello, i32 0, i32 0
|
%src = getelementptr [6 x i8], [6 x i8]* @hello, i32 0, i32 0
|
||||||
|
|
Loading…
Reference in New Issue