summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDevin Coughlin <dcoughlin@apple.com>2015-12-03 19:41:24 +0000
committerDevin Coughlin <dcoughlin@apple.com>2015-12-03 19:41:24 +0000
commitdfde655461d47181c7da3b8eb625025079285dae (patch)
treef1e278faae6a3d5598d4f2e8be4971535f328802
parent9ebe30b265318b37657551f7ba9b080389e29be3 (diff)
downloadbcm5719-llvm-dfde655461d47181c7da3b8eb625025079285dae.tar.gz
bcm5719-llvm-dfde655461d47181c7da3b8eb625025079285dae.zip
[analyzer] Suppress stack address escape on CK_CopyAndAutoreleaseBlockObject.
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. llvm-svn: 254639
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp9
-rw-r--r--clang/test/Analysis/lambdas.mm8
2 files changed, 13 insertions, 4 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp
index 2eefb93e23a..79fc701d6d5 100644
--- a/clang/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp
@@ -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);
}
diff --git a/clang/test/Analysis/lambdas.mm b/clang/test/Analysis/lambdas.mm
index 1061bbf7160..0af916654f4 100644
--- a/clang/test/Analysis/lambdas.mm
+++ b/clang/test/Analysis/lambdas.mm
@@ -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;
OpenPOWER on IntegriCloud