diff options
author | Zhanyong Wan <wan@google.com> | 2010-11-22 08:45:56 +0000 |
---|---|---|
committer | Zhanyong Wan <wan@google.com> | 2010-11-22 08:45:56 +0000 |
commit | 6dace61730e3a7a3d6cd01ce34dbe611cb55ec8c (patch) | |
tree | 4d5dc5ac40ee9b24152758c048d211d8582900f0 | |
parent | 45c2fb1e69fd237ba9b5d1d04493179a85acb9b4 (diff) | |
download | bcm5719-llvm-6dace61730e3a7a3d6cd01ce34dbe611cb55ec8c.tar.gz bcm5719-llvm-6dace61730e3a7a3d6cd01ce34dbe611cb55ec8c.zip |
Fix PR8419. Reviewed by kremenek and xuzhongxing.
llvm-svn: 119960
-rw-r--r-- | clang/lib/Analysis/CFG.cpp | 17 | ||||
-rw-r--r-- | clang/test/Analysis/misc-ps-region-store.cpp | 19 |
2 files changed, 36 insertions, 0 deletions
diff --git a/clang/lib/Analysis/CFG.cpp b/clang/lib/Analysis/CFG.cpp index b58e9826d33..c5ac453d4dd 100644 --- a/clang/lib/Analysis/CFG.cpp +++ b/clang/lib/Analysis/CFG.cpp @@ -296,6 +296,7 @@ private: CFGBlock *VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E, AddStmtChoice asc); CFGBlock *VisitStmtExpr(StmtExpr *S, AddStmtChoice asc); CFGBlock *VisitSwitchStmt(SwitchStmt *S); + CFGBlock *VisitUnaryOperator(UnaryOperator *U, AddStmtChoice asc); CFGBlock *VisitWhileStmt(WhileStmt *W); CFGBlock *Visit(Stmt *S, AddStmtChoice asc = AddStmtChoice::NotAlwaysAdd); @@ -886,6 +887,9 @@ tryAgain: case Stmt::SwitchStmtClass: return VisitSwitchStmt(cast<SwitchStmt>(S)); + case Stmt::UnaryOperatorClass: + return VisitUnaryOperator(cast<UnaryOperator>(S), asc); + case Stmt::WhileStmtClass: return VisitWhileStmt(cast<WhileStmt>(S)); } @@ -922,6 +926,19 @@ CFGBlock *CFGBuilder::VisitAddrLabelExpr(AddrLabelExpr *A, return Block; } +CFGBlock *CFGBuilder::VisitUnaryOperator(UnaryOperator *U, + AddStmtChoice asc) { + if (asc.alwaysAdd()) { + autoCreateBlock(); + AppendStmt(Block, U, asc); + } + + bool asLVal = U->isIncrementDecrementOp(); + return Visit(U->getSubExpr(), + asLVal ? AddStmtChoice::AsLValueNotAlwaysAdd : + AddStmtChoice::NotAlwaysAdd); +} + CFGBlock *CFGBuilder::VisitBinaryOperator(BinaryOperator *B, AddStmtChoice asc) { if (B->isLogicalOp()) { // && or || diff --git a/clang/test/Analysis/misc-ps-region-store.cpp b/clang/test/Analysis/misc-ps-region-store.cpp index dbdfa772a6b..e87fba41f96 100644 --- a/clang/test/Analysis/misc-ps-region-store.cpp +++ b/clang/test/Analysis/misc-ps-region-store.cpp @@ -159,6 +159,25 @@ int r8375510(R8375510 x, R8375510 y) { for (; ; x++) { } } +// PR8419 -- this used to crash. + +class String8419 { + public: + char& get(int n); + char& operator[](int n); +}; + +char& get8419(); + +void Test8419() { + String8419 s; + ++(s.get(0)); + get8419()--; // used to crash + --s[0]; // used to crash + s[0] &= 1; // used to crash + s[0]++; // used to crash +} + // PR8426 -- this used to crash. void Use(void* to); |