aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Analysis/CFG.cpp11
-rw-r--r--test/Analysis/misc-ps-region-store.m6
2 files changed, 14 insertions, 3 deletions
diff --git a/lib/Analysis/CFG.cpp b/lib/Analysis/CFG.cpp
index f003879b7a..3653500f92 100644
--- a/lib/Analysis/CFG.cpp
+++ b/lib/Analysis/CFG.cpp
@@ -935,8 +935,12 @@ CFGBlock *CFGBuilder::VisitBinaryOperator(BinaryOperator *B,
AppendStmt(Block, B, asc);
}
- Visit(B->getRHS());
- return Visit(B->getLHS());
+ CFGBlock *RBlock = Visit(B->getRHS());
+ CFGBlock *LBlock = Visit(B->getLHS());
+ // If visiting RHS causes us to finish 'Block', e.g. the RHS is a StmtExpr
+ // containing a DoStmt, and the LHS doesn't create a new block, then we should
+ // return RBlock. Otherwise we'll incorrectly return NULL.
+ return (LBlock ? LBlock : RBlock);
}
CFGBlock *CFGBuilder::VisitBlockExpr(BlockExpr *E, AddStmtChoice asc) {
@@ -1736,7 +1740,8 @@ CFGBlock* CFGBuilder::VisitWhileStmt(WhileStmt* W) {
if (Stmt* C = W->getCond()) {
Block = ExitConditionBlock;
EntryConditionBlock = addStmt(C);
- assert(Block == EntryConditionBlock);
+ // The condition might finish the current 'Block'.
+ Block = EntryConditionBlock;
// If this block contains a condition variable, add both the condition
// variable and initializer to the CFG.
diff --git a/test/Analysis/misc-ps-region-store.m b/test/Analysis/misc-ps-region-store.m
index 4378e06536..ed285b422b 100644
--- a/test/Analysis/misc-ps-region-store.m
+++ b/test/Analysis/misc-ps-region-store.m
@@ -1157,6 +1157,12 @@ pr8141 (void) {
}
}
+// Don't crash when building the CFG.
+void do_not_crash(int x) {
+ while (x - ({do {} while (0); x; })) {
+ }
+}
+
// <rdar://problem/8424269> - Handle looking at the size of a VLA in
// ArrayBoundChecker. Nothing intelligent (yet); just don't crash.
typedef struct RDar8424269_A {