summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/lib/StaticAnalyzer/Core/MemRegion.cpp9
-rw-r--r--clang/test/Analysis/blocks.m48
2 files changed, 54 insertions, 3 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/MemRegion.cpp b/clang/lib/StaticAnalyzer/Core/MemRegion.cpp
index 1fa675433b5..5ac845825c8 100644
--- a/clang/lib/StaticAnalyzer/Core/MemRegion.cpp
+++ b/clang/lib/StaticAnalyzer/Core/MemRegion.cpp
@@ -824,9 +824,12 @@ const VarRegion* MemRegionManager::getVarRegion(const VarDecl *D,
QualType T;
if (const TypeSourceInfo *TSI = BD->getSignatureAsWritten())
T = TSI->getType();
- else
- T = getContext().getFunctionNoProtoType(getContext().VoidTy);
-
+ if (T.isNull())
+ T = getContext().VoidTy;
+ if (!T->getAs<FunctionType>())
+ T = getContext().getFunctionNoProtoType(T);
+ T = getContext().getBlockPointerType(T);
+
const BlockTextRegion *BTR =
getBlockTextRegion(BD, C.getCanonicalType(T),
STC->getAnalysisDeclContext());
diff --git a/clang/test/Analysis/blocks.m b/clang/test/Analysis/blocks.m
index 62d53607b53..4dbe9517207 100644
--- a/clang/test/Analysis/blocks.m
+++ b/clang/test/Analysis/blocks.m
@@ -162,3 +162,51 @@ void blockCapturesItselfInTheLoop(int x, int m) {
}
assignData(x);
}
+
+// Blocks that called the function they were contained in that also have
+// static locals caused crashes.
+// rdar://problem/21698099
+void takeNonnullBlock(void (^)(void)) __attribute__((nonnull));
+void takeNonnullIntBlock(int (^)(void)) __attribute__((nonnull));
+
+void testCallContainingWithSignature1()
+{
+ takeNonnullBlock(^{
+ static const char str[] = "Lost connection to sharingd";
+ testCallContainingWithSignature1();
+ });
+}
+
+void testCallContainingWithSignature2()
+{
+ takeNonnullBlock(^void{
+ static const char str[] = "Lost connection to sharingd";
+ testCallContainingWithSignature2();
+ });
+}
+
+void testCallContainingWithSignature3()
+{
+ takeNonnullBlock(^void(){
+ static const char str[] = "Lost connection to sharingd";
+ testCallContainingWithSignature3();
+ });
+}
+
+void testCallContainingWithSignature4()
+{
+ takeNonnullBlock(^void(void){
+ static const char str[] = "Lost connection to sharingd";
+ testCallContainingWithSignature4();
+ });
+}
+
+void testCallContainingWithSignature5()
+{
+ takeNonnullIntBlock(^{
+ static const char str[] = "Lost connection to sharingd";
+ testCallContainingWithSignature5();
+ return 0;
+ });
+}
+
OpenPOWER on IntegriCloud