[PATCH] D40009: [Lint] Don't warn about passing alloca'd value to tail call if using byval

Mikael Holmén via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 14 02:12:32 PST 2017


uabelho created this revision.

This fixes PR35241.

When using byval, the data is effectively copied as part of the call
anyway, so the pointer returned by the alloca will not be leaked to the
callee and thus there is no reason to issue a warning.


https://reviews.llvm.org/D40009

Files:
  lib/Analysis/Lint.cpp
  test/Analysis/Lint/tail-call-byval.ll


Index: test/Analysis/Lint/tail-call-byval.ll
===================================================================
--- /dev/null
+++ test/Analysis/Lint/tail-call-byval.ll
@@ -0,0 +1,33 @@
+; RUN: opt < %s -lint -disable-output 2>&1 | FileCheck %s
+
+%s = type { i8 }
+
+declare void @f1(%s*)
+
+define void @f2() {
+entry:
+  %c = alloca %s
+  tail call void @f1(%s* %c)
+  ret void
+}
+
+; Lint should complain about the tail call passing the alloca'd value %c to f1.
+; CHECK: Undefined behavior: Call with "tail" keyword references alloca
+; CHECK-NEXT:  tail call void @f1(%s* %c)
+
+declare void @f3(%s* byval)
+
+define void @f4() {
+entry:
+  %c = alloca %s
+  tail call void @f3(%s* byval %c)
+  ret void
+}
+
+; Lint should not complain about passing the alloca'd %c since it's passed
+; byval, effectively copying the data to the stack instead of leaking the
+; pointer itself.
+; CHECK-NOT: Undefined behavior: Call with "tail" keyword references alloca
+; CHECK-NOT:  tail call void @f3(%s* byval %c)
+
+
Index: lib/Analysis/Lint.cpp
===================================================================
--- lib/Analysis/Lint.cpp
+++ lib/Analysis/Lint.cpp
@@ -285,15 +285,25 @@
     }
   }
 
-  if (CS.isCall() && cast<CallInst>(CS.getInstruction())->isTailCall())
-    for (CallSite::arg_iterator AI = CS.arg_begin(), AE = CS.arg_end();
-         AI != AE; ++AI) {
-      Value *Obj = findValue(*AI, /*OffsetOk=*/true);
-      Assert(!isa<AllocaInst>(Obj),
-             "Undefined behavior: Call with \"tail\" keyword references "
-             "alloca",
-             &I);
+  if (CS.isCall()) {
+    const CallInst *CI = cast<CallInst>(CS.getInstruction());
+    if (CI->isTailCall()) {
+      const AttributeList &PAL = CI->getAttributes();
+      unsigned ArgNo = 0;
+      for (CallSite::arg_iterator AI = CS.arg_begin(), AE = CS.arg_end();
+           AI != AE; ++AI) {
+        // Skip ByVal arguments since they will be memcpy'd to the callee's
+        // stack anyway.
+        if (PAL.hasParamAttribute(ArgNo++, Attribute::ByVal))
+          continue;
+        Value *Obj = findValue(*AI, /*OffsetOk=*/true);
+        Assert(!isa<AllocaInst>(Obj),
+               "Undefined behavior: Call with \"tail\" keyword references "
+               "alloca",
+               &I);
+      }
     }
+  }
 
 
   if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(&I))


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D40009.122796.patch
Type: text/x-patch
Size: 2373 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20171114/c13f8918/attachment.bin>


More information about the llvm-commits mailing list