diff options
| author | Jordan Rose <jordan_rose@apple.com> | 2013-05-22 18:09:44 +0000 |
|---|---|---|
| committer | Jordan Rose <jordan_rose@apple.com> | 2013-05-22 18:09:44 +0000 |
| commit | 1bfe9c787f3eea44b7430bfe62d0cb1286b34e47 (patch) | |
| tree | 6d2d1ec8a44588d3b37fd795e0a21c2354eb03eb | |
| parent | 142736fc64e669175a99516d93d81730f8b21481 (diff) | |
| download | bcm5719-llvm-1bfe9c787f3eea44b7430bfe62d0cb1286b34e47.tar.gz bcm5719-llvm-1bfe9c787f3eea44b7430bfe62d0cb1286b34e47.zip | |
[analyzer] Don't crash if a block doesn't have a type signature.
Currently, blocks instantiated in templates lose their "signature as
written"; it's not clear if this is intentional. Change the analyzer's
use of BlockDecl::getSignatureAsWritten to check whether or not the
signature is actually there.
<rdar://problem/13954714>
llvm-svn: 182497
| -rw-r--r-- | clang/lib/StaticAnalyzer/Core/CallEvent.cpp | 7 | ||||
| -rw-r--r-- | clang/lib/StaticAnalyzer/Core/MemRegion.cpp | 15 | ||||
| -rw-r--r-- | clang/test/Analysis/templates.cpp | 22 |
3 files changed, 39 insertions, 5 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/CallEvent.cpp b/clang/lib/StaticAnalyzer/Core/CallEvent.cpp index dfd20b8b332..8ac09ebb2d1 100644 --- a/clang/lib/StaticAnalyzer/Core/CallEvent.cpp +++ b/clang/lib/StaticAnalyzer/Core/CallEvent.cpp @@ -245,10 +245,13 @@ QualType CallEvent::getDeclaredResultType(const Decl *D) { // Blocks are difficult because the return type may not be stored in the // BlockDecl itself. The AST should probably be enhanced, but for now we // just do what we can. - QualType Ty = BD->getSignatureAsWritten()->getType(); - if (const FunctionType *FT = Ty->getAs<FunctionType>()) + // FIXME: All blocks should have signatures-as-written, even if the return + // type is inferred. (That's signified is with a dependent result type.) + if (const TypeSourceInfo *TSI = BD->getSignatureAsWritten()) { + const FunctionType *FT = TSI->getType()->castAs<FunctionType>(); if (!FT->getResultType()->isDependentType()) return FT->getResultType(); + } return QualType(); } diff --git a/clang/lib/StaticAnalyzer/Core/MemRegion.cpp b/clang/lib/StaticAnalyzer/Core/MemRegion.cpp index 42073d4841f..31ac86bea66 100644 --- a/clang/lib/StaticAnalyzer/Core/MemRegion.cpp +++ b/clang/lib/StaticAnalyzer/Core/MemRegion.cpp @@ -806,10 +806,19 @@ const VarRegion* MemRegionManager::getVarRegion(const VarDecl *D, sReg = getGlobalsRegion(MemRegion::StaticGlobalSpaceRegionKind, getFunctionTextRegion(cast<NamedDecl>(STCD))); else if (const BlockDecl *BD = dyn_cast<BlockDecl>(STCD)) { + // FIXME: The fallback type here is totally bogus -- though it should + // never be queried, it will prevent uniquing with the real + // BlockTextRegion. Ideally we'd fix the AST so that we always had a + // signature. + QualType T; + if (const TypeSourceInfo *TSI = BD->getSignatureAsWritten()) + T = TSI->getType(); + else + T = getContext().getFunctionNoProtoType(getContext().VoidTy); + const BlockTextRegion *BTR = - getBlockTextRegion(BD, - C.getCanonicalType(BD->getSignatureAsWritten()->getType()), - STC->getAnalysisDeclContext()); + getBlockTextRegion(BD, C.getCanonicalType(T), + STC->getAnalysisDeclContext()); sReg = getGlobalsRegion(MemRegion::StaticGlobalSpaceRegionKind, BTR); } diff --git a/clang/test/Analysis/templates.cpp b/clang/test/Analysis/templates.cpp index faa5c1a7620..131794a7c93 100644 --- a/clang/test/Analysis/templates.cpp +++ b/clang/test/Analysis/templates.cpp @@ -48,3 +48,25 @@ void testNonTypeTemplateInstantiation() { #endif } +namespace rdar13954714 { + template <bool VALUE> + bool blockInTemplate() { + return (^() { + return VALUE; + })(); + } + + // force instantiation + template bool blockInTemplate<true>(); + + template <bool VALUE> + void blockWithStatic() { + (void)^() { + static int x; + return ++x; + }; + } + + // force instantiation + template void blockWithStatic<true>(); +} |

