[analyzer] Turn an assert into an if condition

Shocker, turns out that terminator conditions that are binary operators
aren't always logical operators.

llvm-svn: 369195
This commit is contained in:
Kristof Umann 2019-08-17 16:49:54 +00:00
parent e3fb2d549b
commit 032e1fdcd4
2 changed files with 15 additions and 5 deletions

View File

@ -1755,10 +1755,9 @@ static bool isAssertlikeBlock(const CFGBlock *B, ASTContext &Context) {
// B1, 'A && B' for B2, and 'A && B || C' for B3. Let's check whether we
// reached the end of the condition!
if (const Stmt *ElseCond = Else->getTerminatorCondition())
if (isa<BinaryOperator>(ElseCond)) {
assert(cast<BinaryOperator>(ElseCond)->isLogicalOp());
return isAssertlikeBlock(Else, Context);
}
if (const auto *BinOp = dyn_cast<BinaryOperator>(ElseCond))
if (BinOp->isLogicalOp())
return isAssertlikeBlock(Else, Context);
return false;
}

View File

@ -459,6 +459,18 @@ void f(int flag) {
} // end of namespace unimportant_write_before_collapse_point
namespace dont_crash_on_nonlogical_binary_operator {
void f6(int x) {
int a[20];
if (x == 25) {} // expected-note{{Assuming 'x' is equal to 25}}
// expected-note@-1{{Taking true branch}}
if (a[x] == 123) {} // expected-warning{{The left operand of '==' is a garbage value due to array index out of bounds}}
// expected-note@-1{{The left operand of '==' is a garbage value due to array index out of bounds}}
}
} // end of namespace dont_crash_on_nonlogical_binary_operator
namespace dont_track_assertlike_conditions {
extern void __assert_fail(__const char *__assertion, __const char *__file,
@ -532,7 +544,6 @@ void f(int flag) {
}
#undef assert
} // end of namespace dont_track_assertlike_and_conditions
namespace dont_track_assertlike_or_conditions {