diff options
| author | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-07-24 21:02:14 +0000 |
|---|---|---|
| committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-07-24 21:02:14 +0000 |
| commit | f676e45e5f505804cdc9d7c2ee819c94cbac56dd (patch) | |
| tree | d0e55e770da8a0a14f1e5443be99271734481c1e | |
| parent | 342cf787ef3df1ac3479a2e9e10597b1bd3b9264 (diff) | |
| download | bcm5719-llvm-f676e45e5f505804cdc9d7c2ee819c94cbac56dd.tar.gz bcm5719-llvm-f676e45e5f505804cdc9d7c2ee819c94cbac56dd.zip | |
When a && or || appears as the condition of a ?:, perform appropriate
short-circuiting when building the CFG. Also be sure to skip parens before
checking for the && / || special cases. Finally, fix some crashes in CFG
printing in the presence of calls to destructors for array of array of class
type.
llvm-svn: 160691
| -rw-r--r-- | clang/lib/Analysis/CFG.cpp | 23 | ||||
| -rw-r--r-- | clang/test/Sema/uninit-variables.c | 5 |
2 files changed, 18 insertions, 10 deletions
diff --git a/clang/lib/Analysis/CFG.cpp b/clang/lib/Analysis/CFG.cpp index 1e3fa90c372..12845275954 100644 --- a/clang/lib/Analysis/CFG.cpp +++ b/clang/lib/Analysis/CFG.cpp @@ -1491,6 +1491,12 @@ CFGBlock *CFGBuilder::VisitConditionalOperator(AbstractConditionalOperator *C, if (badCFG) return 0; + // If the condition is a logical '&&' or '||', build a more accurate CFG. + if (BinaryOperator *Cond = + dyn_cast<BinaryOperator>(C->getCond()->IgnoreParens())) + if (Cond->isLogicalOp()) + return VisitLogicalOperator(Cond, C, LHSBlock, RHSBlock).first; + // Create the block that will contain the condition. Block = createBlock(false); @@ -1708,7 +1714,8 @@ CFGBlock *CFGBuilder::VisitIfStmt(IfStmt *I) { // control-flow transfer of '&&' or '||' go directly into the then/else // blocks directly. if (!I->getConditionVariable()) - if (BinaryOperator *Cond = dyn_cast<BinaryOperator>(I->getCond())) + if (BinaryOperator *Cond = + dyn_cast<BinaryOperator>(I->getCond()->IgnoreParens())) if (Cond->isLogicalOp()) return VisitLogicalOperator(Cond, I, ThenBlock, ElseBlock).first; @@ -1928,7 +1935,8 @@ CFGBlock *CFGBuilder::VisitForStmt(ForStmt *F) { // Specially handle logical operators, which have a slightly // more optimal CFG representation. - if (BinaryOperator *Cond = dyn_cast_or_null<BinaryOperator>(C)) + if (BinaryOperator *Cond = + dyn_cast_or_null<BinaryOperator>(C ? C->IgnoreParens() : 0)) if (Cond->isLogicalOp()) { llvm::tie(EntryConditionBlock, ExitConditionBlock) = VisitLogicalOperator(Cond, F, BodyBlock, LoopSuccessor); @@ -2237,7 +2245,7 @@ CFGBlock *CFGBuilder::VisitWhileStmt(WhileStmt *W) { // Specially handle logical operators, which have a slightly // more optimal CFG representation. - if (BinaryOperator *Cond = dyn_cast<BinaryOperator>(C)) + if (BinaryOperator *Cond = dyn_cast<BinaryOperator>(C->IgnoreParens())) if (Cond->isLogicalOp()) { llvm::tie(EntryConditionBlock, ExitConditionBlock) = VisitLogicalOperator(Cond, W, BodyBlock, @@ -3712,8 +3720,7 @@ static void print_elem(raw_ostream &OS, StmtPrinterHelper* Helper, const Type* T = VD->getType().getTypePtr(); if (const ReferenceType* RT = T->getAs<ReferenceType>()) T = RT->getPointeeType().getTypePtr(); - else if (const Type *ET = T->getArrayElementTypeNoTypeQual()) - T = ET; + T = T->getBaseElementTypeUnsafe(); OS << ".~" << T->getAsCXXRecordDecl()->getName().str() << "()"; OS << " (Implicit destructor)\n"; @@ -3725,11 +3732,7 @@ static void print_elem(raw_ostream &OS, StmtPrinterHelper* Helper, } else if (const CFGMemberDtor *ME = E.getAs<CFGMemberDtor>()) { const FieldDecl *FD = ME->getFieldDecl(); - - const Type *T = FD->getType().getTypePtr(); - if (const Type *ET = T->getArrayElementTypeNoTypeQual()) - T = ET; - + const Type *T = FD->getType()->getBaseElementTypeUnsafe(); OS << "this->" << FD->getName(); OS << ".~" << T->getAsCXXRecordDecl()->getName() << "()"; OS << " (Member object destructor)\n"; diff --git a/clang/test/Sema/uninit-variables.c b/clang/test/Sema/uninit-variables.c index 9257751e471..634ae0dc428 100644 --- a/clang/test/Sema/uninit-variables.c +++ b/clang/test/Sema/uninit-variables.c @@ -503,3 +503,8 @@ int compound_assign_3() { x *= 0; // expected-warning {{variable 'x' is uninitialized}} return x; } + +int self_init_in_cond(int *p) { + int n = ((p && (0 || 1)) && (n = *p)) ? n : -1; // ok + return n; +} |

