diff options
author | Ted Kremenek <kremenek@apple.com> | 2011-01-20 21:25:31 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2011-01-20 21:25:31 +0000 |
commit | cdca8fa97d06516535ff0c0666ab68748585953c (patch) | |
tree | 4d15be1ac808548f2693a8950e7a9bc4adfb2e9b | |
parent | f07426b40d7b45ae5467bb9f4c010cda7a2e6730 (diff) | |
download | bcm5719-llvm-cdca8fa97d06516535ff0c0666ab68748585953c.tar.gz bcm5719-llvm-cdca8fa97d06516535ff0c0666ab68748585953c.zip |
Relax CFG assertions in UninitializedValuesV2 when
handling pseudo-path sensitivity, and instead
use those assertion conditions as dynamic checks.
These assertions would be violated when analyzing
a CFG where some branches where optimized away
during CFG construction because their branch
conditions could be trivially determined.
llvm-svn: 123943
-rw-r--r-- | clang/lib/Analysis/UninitializedValuesV2.cpp | 27 | ||||
-rw-r--r-- | clang/test/SemaCXX/uninit-variables.cpp | 28 |
2 files changed, 41 insertions, 14 deletions
diff --git a/clang/lib/Analysis/UninitializedValuesV2.cpp b/clang/lib/Analysis/UninitializedValuesV2.cpp index 55769bd2db2..121dcf909e4 100644 --- a/clang/lib/Analysis/UninitializedValuesV2.cpp +++ b/clang/lib/Analysis/UninitializedValuesV2.cpp @@ -156,7 +156,7 @@ static BinaryOperator *getLogicalOperatorInChain(const CFGBlock *block) { llvm::BitVector &CFGBlockValues::getBitVector(const CFGBlock *block, const CFGBlock *dstBlock) { unsigned idx = block->getBlockID(); - if (dstBlock && block->succ_size() == 2) { + if (dstBlock && block->succ_size() == 2 && block->pred_size() == 2) { assert(block->getTerminator()); if (getLogicalOperatorInChain(block)) { if (*block->succ_begin() == dstBlock) @@ -460,20 +460,19 @@ static bool runOnBlock(const CFGBlock *block, const CFG &cfg, UninitVariablesHandler *handler = 0) { if (const BinaryOperator *b = getLogicalOperatorInChain(block)) { - assert(block->pred_size() == 2); - assert(block->succ_size() == 2); - assert(block->getTerminatorCondition() == b); - - BVPair valsAB = vals.getPredBitVectors(block); - vals.mergeIntoScratch(*valsAB.first, true); - vals.mergeIntoScratch(*valsAB.second, false); - valsAB.second = &vals.getScratch(); - if (b->getOpcode() == BO_LOr) { - // Ensure the invariant that 'first' corresponds to the true - // branch and 'second' to the false. - std::swap(valsAB.first, valsAB.second); + if (block->pred_size() == 2 && block->succ_size() == 2) { + assert(block->getTerminatorCondition() == b); + BVPair valsAB = vals.getPredBitVectors(block); + vals.mergeIntoScratch(*valsAB.first, true); + vals.mergeIntoScratch(*valsAB.second, false); + valsAB.second = &vals.getScratch(); + if (b->getOpcode() == BO_LOr) { + // Ensure the invariant that 'first' corresponds to the true + // branch and 'second' to the false. + std::swap(valsAB.first, valsAB.second); + } + return vals.updateBitVectors(block, valsAB); } - return vals.updateBitVectors(block, valsAB); } // Default behavior: merge in values of predecessor blocks. diff --git a/clang/test/SemaCXX/uninit-variables.cpp b/clang/test/SemaCXX/uninit-variables.cpp index e971357ca78..0d6920ceb39 100644 --- a/clang/test/SemaCXX/uninit-variables.cpp +++ b/clang/test/SemaCXX/uninit-variables.cpp @@ -13,3 +13,31 @@ int test2_aux() { return x; // no-warning } +// Handle cases where the CFG may constant fold some branches, thus +// mitigating the need for some path-sensitivity in the analysis. +unsigned test3_aux(); +unsigned test3() { + unsigned x = 0; + const bool flag = true; + if (flag && (x = test3_aux()) == 0) { + return x; + } + return x; +} +unsigned test3_b() { + unsigned x ; + const bool flag = true; + if (flag && (x = test3_aux()) == 0) { + x = 1; + } + return x; // no-warning +} +unsigned test3_c() { + unsigned x ; + const bool flag = false; + if (flag && (x = test3_aux()) == 0) { + x = 1; + } + return x; // expected-warning{{use of uninitialized variable 'x'}} +} + |