Skip to content

Commit f61a08b

Browse files
committed
[analyzer] Fix crash inside RangeConstraintManager.cpp introduced by D112621
It seems like `LHS` and `RHS` could be empty range sets. This caused an assertion failure inside RangeConstraintManager. I'm hoisting out the check from the function into the call-site. This way we could assert that we only want to deal with non-empty range sets. The relevant part of the trace: ``` rust-lang#6 0x00007fe6ff5f81a6 __assert_fail_base (/lib64/libc.so.6+0x2f1a6) rust-lang#7 0x00007fe6ff5f8252 (/lib64/libc.so.6+0x2f252) rust-lang#8 0x00000000049caed2 (anonymous namespace)::SymbolicRangeInferrer::VisitBinaryOperator(clang::ento::RangeSet, clang::BinaryOperatorKind, clang::ento::RangeSet, clang::QualType) RangeConstraintManager.cpp:0:0 rust-lang#9 0x00000000049c9867 (anonymous namespace)::SymbolicRangeInferrer::infer(clang::ento::SymExpr const*) RangeConstraintManager.cpp:0:0 rust-lang#10 0x00000000049bebf5 (anonymous namespace)::RangeConstraintManager::assumeSymNE(llvm::IntrusiveRefCntPtr<clang::ento::ProgramState const>, clang::ento::SymExpr const*, llvm::APSInt const&, llvm::APSInt const&) RangeConstraintManager.cpp:0:0 rust-lang#11 0x00000000049d368c clang::ento::RangedConstraintManager::assumeSymUnsupported(llvm::IntrusiveRefCntPtr<clang::ento::ProgramState const>, clang::ento::SymExpr const*, bool) (../../main-github/llvm/build-all/bin/clang+0x49d368c) rust-lang#12 0x00000000049f0b09 clang::ento::SimpleConstraintManager::assumeAux(llvm::IntrusiveRefCntPtr<clang::ento::ProgramState const>, clang::ento::NonLoc, bool) (../../main-github/llvm/build-all/bin/clang+0x49f0b09) rust-lang#13 0x00000000049f096a clang::ento::SimpleConstraintManager::assume(llvm::IntrusiveRefCntPtr<clang::ento::ProgramState const>, clang::ento::NonLoc, bool) (../../main-github/llvm/build-all/bin/clang+0x49f096a) rust-lang#14 0x00000000049f086d clang::ento::SimpleConstraintManager::assumeInternal(llvm::IntrusiveRefCntPtr<clang::ento::ProgramState const>, clang::ento::DefinedSVal, bool) (../../main-github/llvm/build-all/bin/clang+0x49f086d) rust-lang#15 0x000000000492d3e3 clang::ento::ConstraintManager::assumeDual(llvm::IntrusiveRefCntPtr<clang::ento::ProgramState const>, clang::ento::DefinedSVal) (../../main-github/llvm/build-all/bin/clang+0x492d3e3) rust-lang#16 0x0000000004955b6d clang::ento::ExprEngine::evalEagerlyAssumeBinOpBifurcation(clang::ento::ExplodedNodeSet&, clang::ento::ExplodedNodeSet&, clang::Expr const*) (../../main-github/llvm/build-all/bin/clang+0x4955b6d) rust-lang#17 0x00000000049514b6 clang::ento::ExprEngine::Visit(clang::Stmt const*, clang::ento::ExplodedNode*, clang::ento::ExplodedNodeSet&) (../../main-github/llvm/build-all/bin/clang+0x49514b6) rust-lang#18 0x000000000494c73e clang::ento::ExprEngine::ProcessStmt(clang::Stmt const*, clang::ento::ExplodedNode*) (../../main-github/llvm/build-all/bin/clang+0x494c73e) rust-lang#19 0x000000000494c459 clang::ento::ExprEngine::processCFGElement(clang::CFGElement, clang::ento::ExplodedNode*, unsigned int, clang::ento::NodeBuilderContext*) (../../main-github/llvm/build-all/bin/clang+0x494c459) rust-lang#20 0x000000000492f3d0 clang::ento::CoreEngine::HandlePostStmt(clang::CFGBlock const*, unsigned int, clang::ento::ExplodedNode*) (../../main-github/llvm/build-all/bin/clang+0x492f3d0) rust-lang#21 0x000000000492e1f6 clang::ento::CoreEngine::ExecuteWorkList(clang::LocationContext const*, unsigned int, llvm::IntrusiveRefCntPtr<clang::ento::ProgramState const>) (../../main-github/llvm/build-all/bin/clang+0x492e1f6) ``` Differential Revision: https://reviews.llvm.org/D112621
1 parent 8a3efcd commit f61a08b

File tree

2 files changed

+19
-7
lines changed

2 files changed

+19
-7
lines changed

clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp

+8-7
Original file line numberDiff line numberDiff line change
@@ -1363,11 +1363,7 @@ class SymbolicRangeInferrer
13631363

13641364
template <BinaryOperator::Opcode Op>
13651365
RangeSet VisitBinaryOperator(RangeSet LHS, RangeSet RHS, QualType T) {
1366-
// We should propagate information about unfeasbility of one of the
1367-
// operands to the resulting range.
1368-
if (LHS.isEmpty() || RHS.isEmpty()) {
1369-
return RangeFactory.getEmptySet();
1370-
}
1366+
assert(!LHS.isEmpty() && !RHS.isEmpty());
13711367

13721368
Range CoarseLHS = fillGaps(LHS);
13731369
Range CoarseRHS = fillGaps(RHS);
@@ -1618,8 +1614,7 @@ template <>
16181614
RangeSet SymbolicRangeInferrer::VisitBinaryOperator<BO_NE>(RangeSet LHS,
16191615
RangeSet RHS,
16201616
QualType T) {
1621-
1622-
assert(!LHS.isEmpty() && !RHS.isEmpty() && "Both ranges should be non-empty");
1617+
assert(!LHS.isEmpty() && !RHS.isEmpty());
16231618

16241619
if (LHS.getAPSIntType() == RHS.getAPSIntType()) {
16251620
if (intersect(RangeFactory, LHS, RHS).isEmpty())
@@ -1803,6 +1798,12 @@ RangeSet SymbolicRangeInferrer::VisitBinaryOperator<BO_Rem>(Range LHS,
18031798
RangeSet SymbolicRangeInferrer::VisitBinaryOperator(RangeSet LHS,
18041799
BinaryOperator::Opcode Op,
18051800
RangeSet RHS, QualType T) {
1801+
// We should propagate information about unfeasbility of one of the
1802+
// operands to the resulting range.
1803+
if (LHS.isEmpty() || RHS.isEmpty()) {
1804+
return RangeFactory.getEmptySet();
1805+
}
1806+
18061807
switch (Op) {
18071808
case BO_NE:
18081809
return VisitBinaryOperator<BO_NE>(LHS, RHS, T);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// RUN: %clang_analyze_cc1 -analyzer-checker=core -verify %s
2+
// expected-no-diagnostics
3+
4+
namespace bbi_77010 {
5+
int crash_NE(int rhs, int lhs, int x) {
6+
int band = lhs & rhs;
7+
if (0 <= band) {}
8+
if (rhs > 0) {}
9+
return band != x; // no-crash D112621
10+
}
11+
} // namespace bbi_77010

0 commit comments

Comments
 (0)