diff --git a/lib/StaticAnalyzer/Core/CallEvent.cpp b/lib/StaticAnalyzer/Core/CallEvent.cpp index dfd20b8b332b30da1004428fe04163b539a23fe6..8ac09ebb2d1f750359b26563e0813383a220dcc9 100644 --- a/lib/StaticAnalyzer/Core/CallEvent.cpp +++ b/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/lib/StaticAnalyzer/Core/MemRegion.cpp b/lib/StaticAnalyzer/Core/MemRegion.cpp index 42073d4841f74c20bac499c9f1b2f3f86432b56c..31ac86bea663d2016e3d3ddeb57e607d0686bd22 100644 --- a/lib/StaticAnalyzer/Core/MemRegion.cpp +++ b/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/test/Analysis/templates.cpp b/test/Analysis/templates.cpp index faa5c1a762094c1104b80ea1616f669f82b8cbab..131794a7c9319933464d75982e0ea75149484f58 100644 --- a/test/Analysis/templates.cpp +++ b/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>(); +}