aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Analysis/CFG.cpp17
-rw-r--r--test/Analysis/reference.cpp15
2 files changed, 30 insertions, 2 deletions
diff --git a/lib/Analysis/CFG.cpp b/lib/Analysis/CFG.cpp
index 6f2cb41a6e..1d294ae8ea 100644
--- a/lib/Analysis/CFG.cpp
+++ b/lib/Analysis/CFG.cpp
@@ -538,6 +538,15 @@ CFGBlock *CFGBuilder::VisitBinaryOperator(BinaryOperator *B,
addStmt(B->getRHS());
return addStmt(B->getLHS());
}
+ else if (B->isAssignmentOp()) {
+ if (asc.alwaysAdd()) {
+ autoCreateBlock();
+ AppendStmt(Block, B, asc);
+ }
+
+ Visit(B->getRHS());
+ return Visit(B->getLHS(), AddStmtChoice::AsLValueNotAlwaysAdd);
+ }
return VisitStmt(B, asc);
}
@@ -612,8 +621,12 @@ CFGBlock *CFGBuilder::VisitCallExpr(CallExpr *C, AddStmtChoice asc) {
if (!CanThrow(C->getCallee()))
AddEHEdge = false;
- if (!NoReturn && !AddEHEdge)
- return VisitStmt(C, AddStmtChoice::AlwaysAdd);
+ if (!NoReturn && !AddEHEdge) {
+ if (asc.asLValue())
+ return VisitStmt(C, AddStmtChoice::AlwaysAddAsLValue);
+ else
+ return VisitStmt(C, AddStmtChoice::AlwaysAdd);
+ }
if (Block) {
Succ = Block;
diff --git a/test/Analysis/reference.cpp b/test/Analysis/reference.cpp
index 54d7cf57e0..6b962157da 100644
--- a/test/Analysis/reference.cpp
+++ b/test/Analysis/reference.cpp
@@ -9,3 +9,18 @@ void f1() {
if (b != 3)
*p = 1; // no-warning
}
+
+char* ptr();
+char& ref();
+
+// These next two tests just shouldn't crash.
+char t1 () {
+ ref() = 'c';
+ return '0';
+}
+
+// just a sanity test, the same behavior as t1()
+char t2 () {
+ *ptr() = 'c';
+ return '0';
+}