From: Devin Coughlin Date: Thu, 3 Dec 2015 19:41:24 +0000 (+0000) Subject: [analyzer] Suppress stack address escape on CK_CopyAndAutoreleaseBlockObject. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a2892f01674eda2f73cbcaef629a1b2a6915e3ea;p=clang [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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@254639 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp b/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp index 2eefb93e23..79fc701d6d 100644 --- a/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp @@ -156,6 +156,15 @@ void StackAddrEscapeChecker::checkPreStmt(const ReturnStmt *RS, if (isa(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(RetE)) { + if (isa(R) && + ICE->getCastKind() == CK_CopyAndAutoreleaseBlockObject) { + return; + } + } + EmitStackError(C, R, RetE); } diff --git a/test/Analysis/lambdas.mm b/test/Analysis/lambdas.mm index 1061bbf716..0af916654f 100644 --- a/test/Analysis/lambdas.mm +++ b/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;