If we don't know how long a string is we can't fold an _chk version to the
authorEric Christopher <echristo@apple.com>
Tue, 15 Mar 2011 00:25:41 +0000 (00:25 +0000)
committerEric Christopher <echristo@apple.com>
Tue, 15 Mar 2011 00:25:41 +0000 (00:25 +0000)
normal version.

Fixes rdar://9123638

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@127636 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/InstCombine/InstCombineCalls.cpp
test/Transforms/InstCombine/strcpy_chk-64.ll [new file with mode: 0644]

index bfdc17eff7ec9e900a6b6992338df95306bf616f..b5fd0b9af40854ffc94c6efb836fb5b0b5c5e87a 100644 (file)
@@ -759,9 +759,13 @@ protected:
                            dyn_cast<ConstantInt>(CI->getArgOperand(SizeCIOp))) {
       if (SizeCI->isAllOnesValue())
         return true;
-      if (isString)
-        return SizeCI->getZExtValue() >=
-               GetStringLength(CI->getArgOperand(SizeArgOp));
+      if (isString) {
+        uint64_t Len = GetStringLength(CI->getArgOperand(SizeArgOp));
+        // If the length is 0 we don't know how long it is and so we can't
+        // remove the check.
+        if (Len == 0) return false;
+        return SizeCI->getZExtValue() >= Len;
+      }
       if (ConstantInt *Arg = dyn_cast<ConstantInt>(
                                                   CI->getArgOperand(SizeArgOp)))
         return SizeCI->getZExtValue() >= Arg->getZExtValue();
diff --git a/test/Transforms/InstCombine/strcpy_chk-64.ll b/test/Transforms/InstCombine/strcpy_chk-64.ll
new file mode 100644 (file)
index 0000000..036fcbe
--- /dev/null
@@ -0,0 +1,18 @@
+; RUN: opt < %s -instcombine -S | FileCheck %s
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-apple-darwin10.0.0"
+
+define void @func(i8* %i) nounwind ssp {
+; CHECK: @func
+; CHECK: @__strcpy_chk(i8* %arraydecay, i8* %i, i64 32)
+entry:
+  %s = alloca [32 x i8], align 16
+  %arraydecay = getelementptr inbounds [32 x i8]* %s, i32 0, i32 0
+  %call = call i8* @__strcpy_chk(i8* %arraydecay, i8* %i, i64 32)
+  call void @func2(i8* %arraydecay)
+  ret void
+}
+
+declare i8* @__strcpy_chk(i8*, i8*, i64) nounwind
+
+declare void @func2(i8*)