diff options
-rw-r--r-- | lib/Analysis/CFG.cpp | 22 | ||||
-rw-r--r-- | test/Analysis/dead-stores.c | 12 |
2 files changed, 32 insertions, 2 deletions
diff --git a/lib/Analysis/CFG.cpp b/lib/Analysis/CFG.cpp index 258f67e1d5..79ca8114a7 100644 --- a/lib/Analysis/CFG.cpp +++ b/lib/Analysis/CFG.cpp @@ -521,6 +521,18 @@ CFGBlock *CFGBuilder::VisitCallExpr(CallExpr *C, bool alwaysAdd) { } CFGBlock *CFGBuilder::VisitChooseExpr(ChooseExpr *C) { + // See if this is a known constant. + bool KnownTrue = false; + bool KnownFalse = false; + Expr::EvalResult Result; + if (C->getCond()->Evaluate(Result, *Context) + && Result.Val.isInt()) { + if (Result.Val.getInt().getBoolValue()) + KnownTrue = true; + else + KnownFalse = true; + } + CFGBlock* ConfluenceBlock = Block ? Block : createBlock(); ConfluenceBlock->appendStmt(C); if (!FinishBlock(ConfluenceBlock)) @@ -539,8 +551,14 @@ CFGBlock *CFGBuilder::VisitChooseExpr(ChooseExpr *C) { return 0; Block = createBlock(false); - Block->addSuccessor(LHSBlock); - Block->addSuccessor(RHSBlock); + if (KnownFalse) + Block->addSuccessor(0); + else + Block->addSuccessor(LHSBlock); + if (KnownTrue) + Block->addSuccessor(0); + else + Block->addSuccessor(RHSBlock); Block->setTerminator(C); return addStmt(C->getCond()); } diff --git a/test/Analysis/dead-stores.c b/test/Analysis/dead-stores.c index 5f14010e5f..f3ff1451be 100644 --- a/test/Analysis/dead-stores.c +++ b/test/Analysis/dead-stores.c @@ -207,6 +207,8 @@ void f22() { int y16 = 4; int y17 = 4; int y18 = 4; + int y19 = 4; + int y20 = 4; ++x; // expected-warning{{never read}} ++y1; @@ -227,6 +229,8 @@ void f22() { ++y16; ++y17; ++y18; + ++y19; + ++y20; switch (j) { case 1: @@ -324,5 +328,13 @@ void f22() { } (void)y18; break; + case 17: + __builtin_choose_expr(0, (void)x, ((void)y19, ({ return; }))); + (void)x; + break; + case 19: + __builtin_choose_expr(1, ((void)y20, ({ return; })), (void)x); + (void)x; + break; } } |