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 | b930d7adb7cb7642c9c49b39df04ebd5cbfa713a (patch) | |
tree | 403e393ad9683ef16b8154dca8a1f0da89fa4228 /lib/AST/ParentMap.cpp | |
parent | 03d9f34a96ea28eaa698cc779462a1ce1dc79105 (diff) |
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.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@68195 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/ParentMap.cpp')
-rw-r--r-- | lib/AST/ParentMap.cpp | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/lib/AST/ParentMap.cpp b/lib/AST/ParentMap.cpp index 54472ecb96..877b43b6de 100644 --- a/lib/AST/ParentMap.cpp +++ b/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; + } +} + |