]> granicus.if.org Git - clang/commitdiff
[analyzer] Suppress stack address escape on CK_CopyAndAutoreleaseBlockObject.
authorDevin Coughlin <dcoughlin@apple.com>
Thu, 3 Dec 2015 19:41:24 +0000 (19:41 +0000)
committerDevin Coughlin <dcoughlin@apple.com>
Thu, 3 Dec 2015 19:41:24 +0000 (19:41 +0000)
Don't warn about addresses of stack-allocated blocks escaping if the block
region was cast with CK_CopyAndAutoreleaseBlockObject. These casts, which
are introduced in the implicit conversion operator for lambda-to-block
conversions, cause the block to be copied to the heap -- so the warning is
spurious.

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

lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp
test/Analysis/lambdas.mm

index 2eefb93e23a5eb775b69b30118d9081e611d46a4..79fc701d6d58c1172a0c3361557eb77f53e5808d 100644 (file)
@@ -156,6 +156,15 @@ void StackAddrEscapeChecker::checkPreStmt(const ReturnStmt *RS,
   if (isa<CXXConstructExpr>(RetE) && RetE->getType()->isRecordType())
     return;
 
+  // The CK_CopyAndAutoreleaseBlockObject cast causes the block to be copied
+  // so the stack address is not escaping here.
+  if (auto *ICE = dyn_cast<ImplicitCastExpr>(RetE)) {
+    if (isa<BlockDataRegion>(R) &&
+        ICE->getCastKind() == CK_CopyAndAutoreleaseBlockObject) {
+      return;
+    }
+  }
+
   EmitStackError(C, R, RetE);
 }
 
index 1061bbf7160de12bd0226e7b1d9caf765c801666..0af916654f46aaee6c818581ed443a881353c0fb 100644 (file)
@@ -76,10 +76,10 @@ void castToBlockAndInline() {
 }
 
 void castLambdaInLocalBlock() {
-  // FIXME: This results in a spurious
-  // "Address of stack-allocated block declared on line XX returned to caller" warning
-  // because we're not handling lambda to block conversions properly in ExprEngine.
-  auto lambda = []{ }; // expected-warning {{Address of stack-allocated block declared on line}}
+  // Make sure we don't emit a spurious diagnostic about the address of a block
+  // escaping in the implicit conversion operator method for lambda-to-block
+  // conversions.
+  auto lambda = []{ }; // no-warning
 
   void(^block)() = lambda;
   (void)block;