summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJordan Rose <jordan_rose@apple.com>2013-05-22 18:09:44 +0000
committerJordan Rose <jordan_rose@apple.com>2013-05-22 18:09:44 +0000
commit1bfe9c787f3eea44b7430bfe62d0cb1286b34e47 (patch)
tree6d2d1ec8a44588d3b37fd795e0a21c2354eb03eb
parent142736fc64e669175a99516d93d81730f8b21481 (diff)
downloadbcm5719-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.cpp7
-rw-r--r--clang/lib/StaticAnalyzer/Core/MemRegion.cpp15
-rw-r--r--clang/test/Analysis/templates.cpp22
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>();
+}
OpenPOWER on IntegriCloud