diff options
author | Ted Kremenek <kremenek@apple.com> | 2009-04-01 06:52:48 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2009-04-01 06:52:48 +0000 |
commit | 8b0dba358a3fae6695aff56a150b9e18f66e0cf3 (patch) | |
tree | 39336620737513cc431993a0a611585d0ecf7b34 /clang/lib/AST/ParentMap.cpp | |
parent | 3088a31e96ab75f567e272dc5f6ca5fe347d6caa (diff) | |
download | bcm5719-llvm-8b0dba358a3fae6695aff56a150b9e18f66e0cf3.tar.gz bcm5719-llvm-8b0dba358a3fae6695aff56a150b9e18f66e0cf3.zip |
Fix: <rdar://problem/6740387>. Sending nil to an object that returns a struct
should only be an error if that value is consumed. This fix was largely
accomplished by moving 'isConsumedExpr' back to ParentMap.
llvm-svn: 68195
Diffstat (limited to 'clang/lib/AST/ParentMap.cpp')
-rw-r--r-- | clang/lib/AST/ParentMap.cpp | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/clang/lib/AST/ParentMap.cpp b/clang/lib/AST/ParentMap.cpp index 54472ecb963..877b43b6de9 100644 --- a/clang/lib/AST/ParentMap.cpp +++ b/clang/lib/AST/ParentMap.cpp @@ -45,3 +45,43 @@ Stmt* ParentMap::getParent(Stmt* S) const { MapTy::iterator I = M->find(S); return I == M->end() ? 0 : I->second; } + +bool ParentMap::isConsumedExpr(Expr* E) const { + Stmt *P = getParent(E); + Stmt *DirectChild = E; + + // Ignore parents that are parentheses or casts. + while (P && (isa<ParenExpr>(E) || isa<CastExpr>(E))) { + DirectChild = P; + P = getParent(P); + } + + if (!P) + return false; + + switch (P->getStmtClass()) { + default: + return isa<Expr>(P); + case Stmt::DeclStmtClass: + return true; + case Stmt::BinaryOperatorClass: { + BinaryOperator *BE = cast<BinaryOperator>(P); + return BE->getOpcode()==BinaryOperator::Comma && DirectChild==BE->getLHS(); + } + case Stmt::ForStmtClass: + return DirectChild == cast<ForStmt>(P)->getCond(); + case Stmt::WhileStmtClass: + return DirectChild == cast<WhileStmt>(P)->getCond(); + case Stmt::DoStmtClass: + return DirectChild == cast<DoStmt>(P)->getCond(); + case Stmt::IfStmtClass: + return DirectChild == cast<IfStmt>(P)->getCond(); + case Stmt::IndirectGotoStmtClass: + return DirectChild == cast<IndirectGotoStmt>(P)->getTarget(); + case Stmt::SwitchStmtClass: + return DirectChild == cast<SwitchStmt>(P)->getCond(); + case Stmt::ReturnStmtClass: + return true; + } +} + |