mirror of https://github.com/microsoft/clang.git
Revert "[analyzer] Support generating and reasoning over more symbolic constraint types"
Assertion `Loc::isLocType(SSE->getLHS()->getType())' failed in Analysis/PR3991.m
This reverts commit e469ff2759
.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@307853 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
6deacb219c
commit
f3ab09d9a0
|
@ -125,14 +125,8 @@ public:
|
|||
return OS.str();
|
||||
}
|
||||
|
||||
std::string VisitIntSymExpr(const IntSymExpr *S) {
|
||||
std::string Str;
|
||||
llvm::raw_string_ostream OS(Str);
|
||||
OS << S->getLHS()
|
||||
<< std::string(BinaryOperator::getOpcodeStr(S->getOpcode())) << " "
|
||||
<< "(" << Visit(S->getRHS()) << ") ";
|
||||
return OS.str();
|
||||
}
|
||||
// TODO: IntSymExpr doesn't appear in practice.
|
||||
// Add the relevant code once it does.
|
||||
|
||||
std::string VisitSymSymExpr(const SymSymExpr *S) {
|
||||
return "(" + Visit(S->getLHS()) + ") " +
|
||||
|
@ -140,10 +134,8 @@ public:
|
|||
" (" + Visit(S->getRHS()) + ")";
|
||||
}
|
||||
|
||||
std::string VisitSymbolCast(const SymbolCast *S) {
|
||||
return "cast of type '" + S->getType().getAsString() + "' of " +
|
||||
Visit(S->getOperand());
|
||||
}
|
||||
// TODO: SymbolCast doesn't appear in practice.
|
||||
// Add the relevant code once it does.
|
||||
|
||||
std::string VisitSymbolicRegion(const SymbolicRegion *R) {
|
||||
// Explain 'this' object here.
|
||||
|
|
|
@ -100,7 +100,7 @@ SValBuilder::getRegionValueSymbolVal(const TypedValueRegion* region) {
|
|||
|
||||
if (T->isNullPtrType())
|
||||
return makeZeroVal(T);
|
||||
|
||||
|
||||
if (!SymbolManager::canSymbolicate(T))
|
||||
return UnknownVal();
|
||||
|
||||
|
@ -354,6 +354,9 @@ SVal SValBuilder::makeSymExprValNN(ProgramStateRef State,
|
|||
BinaryOperator::Opcode Op,
|
||||
NonLoc LHS, NonLoc RHS,
|
||||
QualType ResultTy) {
|
||||
if (!State->isTainted(RHS) && !State->isTainted(LHS))
|
||||
return UnknownVal();
|
||||
|
||||
const SymExpr *symLHS = LHS.getAsSymExpr();
|
||||
const SymExpr *symRHS = RHS.getAsSymExpr();
|
||||
// TODO: When the Max Complexity is reached, we should conjure a symbol
|
||||
|
@ -361,7 +364,7 @@ SVal SValBuilder::makeSymExprValNN(ProgramStateRef State,
|
|||
const unsigned MaxComp = 10000; // 100000 28X
|
||||
|
||||
if (symLHS && symRHS &&
|
||||
(symLHS->computeComplexity() + symRHS->computeComplexity()) < MaxComp)
|
||||
(symLHS->computeComplexity() + symRHS->computeComplexity()) < MaxComp)
|
||||
return makeNonLoc(symLHS, Op, symRHS, ResultTy);
|
||||
|
||||
if (symLHS && symLHS->computeComplexity() < MaxComp)
|
||||
|
|
|
@ -669,12 +669,12 @@ SVal SimpleSValBuilder::evalBinOpLL(ProgramStateRef state,
|
|||
// If one of the operands is a symbol and the other is a constant,
|
||||
// build an expression for use by the constraint manager.
|
||||
if (SymbolRef rSym = rhs.getAsLocSymbol()) {
|
||||
const llvm::APSInt &lVal = lhs.castAs<loc::ConcreteInt>().getValue();
|
||||
|
||||
// Prefer expressions with symbols on the left
|
||||
// We can only build expressions with symbols on the left,
|
||||
// so we need a reversible operator.
|
||||
if (!BinaryOperator::isComparisonOp(op))
|
||||
return makeNonLoc(lVal, op, rSym, resultTy);
|
||||
return UnknownVal();
|
||||
|
||||
const llvm::APSInt &lVal = lhs.castAs<loc::ConcreteInt>().getValue();
|
||||
op = BinaryOperator::reverseComparisonOp(op);
|
||||
return makeNonLoc(rSym, op, lVal, resultTy);
|
||||
}
|
||||
|
@ -994,8 +994,7 @@ const llvm::APSInt *SimpleSValBuilder::getKnownValue(ProgramStateRef state,
|
|||
if (SymbolRef Sym = V.getAsSymbol())
|
||||
return state->getConstraintManager().getSymVal(state, Sym);
|
||||
|
||||
// FIXME: Add support for SymExprs in RangeConstraintManager.
|
||||
|
||||
// FIXME: Add support for SymExprs.
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -1020,11 +1019,8 @@ SVal SimpleSValBuilder::simplifySVal(ProgramStateRef State, SVal V) {
|
|||
return nonloc::SymbolVal(S);
|
||||
}
|
||||
|
||||
SVal VisitIntSymExpr(const IntSymExpr *S) {
|
||||
SVal RHS = Visit(S->getRHS());
|
||||
SVal LHS = SVB.makeIntVal(S->getLHS());
|
||||
return SVB.evalBinOp(State, S->getOpcode(), LHS, RHS, S->getType());
|
||||
}
|
||||
// TODO: Support SymbolCast. Support IntSymExpr when/if we actually
|
||||
// start producing them.
|
||||
|
||||
SVal VisitSymIntExpr(const SymIntExpr *S) {
|
||||
SVal LHS = Visit(S->getLHS());
|
||||
|
@ -1049,11 +1045,6 @@ SVal SimpleSValBuilder::simplifySVal(ProgramStateRef State, SVal V) {
|
|||
return SVB.evalBinOp(State, S->getOpcode(), LHS, RHS, S->getType());
|
||||
}
|
||||
|
||||
SVal VisitSymbolCast(const SymbolCast *S) {
|
||||
SVal V = Visit(S->getOperand());
|
||||
return SVB.evalCast(V, S->getType(), S->getOperand()->getType());
|
||||
}
|
||||
|
||||
SVal VisitSymSymExpr(const SymSymExpr *S) {
|
||||
SVal LHS = Visit(S->getLHS());
|
||||
SVal RHS = Visit(S->getRHS());
|
||||
|
@ -1067,8 +1058,7 @@ SVal SimpleSValBuilder::simplifySVal(ProgramStateRef State, SVal V) {
|
|||
SVal VisitNonLocSymbolVal(nonloc::SymbolVal V) {
|
||||
// Simplification is much more costly than computing complexity.
|
||||
// For high complexity, it may be not worth it.
|
||||
// Use a lower bound to avoid recursive blowup, e.g. on PR24184.cpp
|
||||
if (V.getSymbol()->computeComplexity() > 10)
|
||||
if (V.getSymbol()->computeComplexity() > 100)
|
||||
return V;
|
||||
return Visit(V.getSymbol());
|
||||
}
|
||||
|
|
|
@ -1034,19 +1034,16 @@ ProgramStateRef Z3ConstraintManager::assumeSym(ProgramStateRef State,
|
|||
ProgramStateRef Z3ConstraintManager::assumeSymInclusiveRange(
|
||||
ProgramStateRef State, SymbolRef Sym, const llvm::APSInt &From,
|
||||
const llvm::APSInt &To, bool InRange) {
|
||||
ASTContext &Ctx = getBasicVals().getContext();
|
||||
// FIXME: This should be a cast from a 1-bit integer type to a boolean type,
|
||||
// but the former is not available in Clang. Instead, extend the APSInt
|
||||
// directly.
|
||||
bool isBoolTy = From.getBitWidth() == 1 && getAPSIntType(From).isNull();
|
||||
|
||||
QualType RetTy;
|
||||
// The expression may be casted, so we cannot call getZ3DataExpr() directly
|
||||
Z3Expr Exp = getZ3Expr(Sym, &RetTy);
|
||||
QualType RTy = isBoolTy ? Ctx.BoolTy : getAPSIntType(From);
|
||||
Z3Expr FromExp =
|
||||
isBoolTy ? Z3Expr::fromAPSInt(From.extend(Ctx.getTypeSize(Ctx.BoolTy)))
|
||||
: Z3Expr::fromAPSInt(From);
|
||||
|
||||
assert((getAPSIntType(From) == getAPSIntType(To)) &&
|
||||
"Range values have different types!");
|
||||
QualType RTy = getAPSIntType(From);
|
||||
bool isSignedTy = RetTy->isSignedIntegerOrEnumerationType();
|
||||
Z3Expr FromExp = Z3Expr::fromAPSInt(From);
|
||||
Z3Expr ToExp = Z3Expr::fromAPSInt(To);
|
||||
|
||||
// Construct single (in)equality
|
||||
if (From == To)
|
||||
|
@ -1054,10 +1051,6 @@ ProgramStateRef Z3ConstraintManager::assumeSymInclusiveRange(
|
|||
getZ3BinExpr(Exp, RetTy, InRange ? BO_EQ : BO_NE,
|
||||
FromExp, RTy, nullptr));
|
||||
|
||||
assert((getAPSIntType(From) == getAPSIntType(To)) &&
|
||||
"Range values have different types!");
|
||||
|
||||
Z3Expr ToExp = Z3Expr::fromAPSInt(To);
|
||||
// Construct two (in)equalities, and a logical and/or
|
||||
Z3Expr LHS =
|
||||
getZ3BinExpr(Exp, RetTy, InRange ? BO_GE : BO_LT, FromExp, RTy, nullptr);
|
||||
|
@ -1065,8 +1058,7 @@ ProgramStateRef Z3ConstraintManager::assumeSymInclusiveRange(
|
|||
getZ3BinExpr(Exp, RetTy, InRange ? BO_LE : BO_GT, ToExp, RTy, nullptr);
|
||||
return assumeZ3Expr(
|
||||
State, Sym,
|
||||
Z3Expr::fromBinOp(LHS, InRange ? BO_LAnd : BO_LOr, RHS,
|
||||
RetTy->isSignedIntegerOrEnumerationType()));
|
||||
Z3Expr::fromBinOp(LHS, InRange ? BO_LAnd : BO_LOr, RHS, isSignedTy));
|
||||
}
|
||||
|
||||
ProgramStateRef Z3ConstraintManager::assumeSymUnsupported(ProgramStateRef State,
|
||||
|
@ -1414,7 +1406,6 @@ void Z3ConstraintManager::doTypeConversion(Z3Expr &LHS, Z3Expr &RHS,
|
|||
QualType <y, QualType &RTy) const {
|
||||
ASTContext &Ctx = getBasicVals().getContext();
|
||||
|
||||
assert(!LTy.isNull() && !RTy.isNull() && "Input type is null!");
|
||||
// Perform type conversion
|
||||
if (LTy->isIntegralOrEnumerationType() &&
|
||||
RTy->isIntegralOrEnumerationType()) {
|
||||
|
@ -1477,10 +1468,10 @@ template <typename T,
|
|||
void Z3ConstraintManager::doIntTypeConversion(T &LHS, QualType <y, T &RHS,
|
||||
QualType &RTy) const {
|
||||
ASTContext &Ctx = getBasicVals().getContext();
|
||||
|
||||
uint64_t LBitWidth = Ctx.getTypeSize(LTy);
|
||||
uint64_t RBitWidth = Ctx.getTypeSize(RTy);
|
||||
|
||||
assert(!LTy.isNull() && !RTy.isNull() && "Input type is null!");
|
||||
// Always perform integer promotion before checking type equality.
|
||||
// Otherwise, e.g. (bool) a + (bool) b could trigger a backend assertion
|
||||
if (LTy->isPromotableIntegerType()) {
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import copy
|
||||
import lit.formats
|
||||
import lit.TestRunner
|
||||
|
||||
|
@ -9,21 +8,18 @@ class AnalyzerTest(lit.formats.ShTest):
|
|||
results = []
|
||||
|
||||
# Parse any test requirements ('REQUIRES: ')
|
||||
saved_test = copy.deepcopy(test)
|
||||
saved_test = test
|
||||
lit.TestRunner.parseIntegratedTestScript(test)
|
||||
|
||||
# If the test does not require z3, drop it from the available features
|
||||
# to satisfy tests that explicitly require !z3
|
||||
if 'z3' not in test.requires:
|
||||
test.config.available_features.discard('z3')
|
||||
results.append(self.executeWithAnalyzeSubstitution(
|
||||
test, litConfig, '-analyzer-constraints=range'))
|
||||
saved_test, litConfig, '-analyzer-constraints=range'))
|
||||
|
||||
if results[-1].code != lit.Test.PASS:
|
||||
if results[-1].code == lit.Test.FAIL:
|
||||
return results[-1]
|
||||
|
||||
# If z3 backend available, add an additional run line for it
|
||||
if test.config.clang_staticanalyzer_z3 == '1' and '!z3' not in test.requires:
|
||||
if test.config.clang_staticanalyzer_z3 == '1':
|
||||
results.append(self.executeWithAnalyzeSubstitution(
|
||||
saved_test, litConfig, '-analyzer-constraints=z3 -DANALYZER_CM_Z3'))
|
||||
|
||||
|
|
|
@ -7,9 +7,10 @@ void testPersistentConstraints(int x, int y) {
|
|||
// Sanity check
|
||||
CHECK(x); // expected-warning{{TRUE}}
|
||||
CHECK(x & 1); // expected-warning{{TRUE}}
|
||||
|
||||
CHECK(1 - x); // expected-warning{{TRUE}}
|
||||
CHECK(x & y); // expected-warning{{TRUE}}
|
||||
|
||||
// False positives due to SValBuilder giving up on certain kinds of exprs.
|
||||
CHECK(1 - x); // expected-warning{{UNKNOWN}}
|
||||
CHECK(x & y); // expected-warning{{UNKNOWN}}
|
||||
}
|
||||
|
||||
int testConstantShifts_PR18073(int which) {
|
||||
|
@ -28,4 +29,4 @@ int testConstantShifts_PR18073(int which) {
|
|||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -43,7 +43,11 @@ void test_BOOL_initialization(int y) {
|
|||
return;
|
||||
}
|
||||
if (y > 200 && y < 250) {
|
||||
#ifdef ANALYZER_CM_Z3
|
||||
BOOL x = y; // expected-warning {{Assignment of a non-Boolean value}}
|
||||
#else
|
||||
BOOL x = y; // no-warning
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
if (y >= 127 && y < 150) {
|
||||
|
|
|
@ -77,8 +77,7 @@ void testDiagnosableBranchLogical(int a, int b) {
|
|||
|
||||
void testNonDiagnosableBranchArithmetic(int a, int b) {
|
||||
if (a - b) {
|
||||
// expected-note@-1 {{Assuming the condition is true}}
|
||||
// expected-note@-2 {{Taking true branch}}
|
||||
// expected-note@-1 {{Taking true branch}}
|
||||
*(volatile int *)0 = 1; // expected-warning{{Dereference of null pointer}}
|
||||
// expected-note@-1 {{Dereference of null pointer}}
|
||||
}
|
||||
|
@ -1574,75 +1573,12 @@ void testNonDiagnosableBranchArithmetic(int a, int b) {
|
|||
// CHECK-NEXT: <key>end</key>
|
||||
// CHECK-NEXT: <array>
|
||||
// CHECK-NEXT: <dict>
|
||||
// CHECK-NEXT: <key>line</key><integer>79</integer>
|
||||
// CHECK-NEXT: <key>col</key><integer>7</integer>
|
||||
// CHECK-NEXT: <key>file</key><integer>0</integer>
|
||||
// CHECK-NEXT: </dict>
|
||||
// CHECK-NEXT: <dict>
|
||||
// CHECK-NEXT: <key>line</key><integer>79</integer>
|
||||
// CHECK-NEXT: <key>col</key><integer>7</integer>
|
||||
// CHECK-NEXT: <key>file</key><integer>0</integer>
|
||||
// CHECK-NEXT: </dict>
|
||||
// CHECK-NEXT: </array>
|
||||
// CHECK-NEXT: </dict>
|
||||
// CHECK-NEXT: </array>
|
||||
// CHECK-NEXT: </dict>
|
||||
// CHECK-NEXT: <dict>
|
||||
// CHECK-NEXT: <key>kind</key><string>event</string>
|
||||
// CHECK-NEXT: <key>location</key>
|
||||
// CHECK-NEXT: <dict>
|
||||
// CHECK-NEXT: <key>line</key><integer>79</integer>
|
||||
// CHECK-NEXT: <key>col</key><integer>7</integer>
|
||||
// CHECK-NEXT: <key>file</key><integer>0</integer>
|
||||
// CHECK-NEXT: </dict>
|
||||
// CHECK-NEXT: <key>ranges</key>
|
||||
// CHECK-NEXT: <array>
|
||||
// CHECK-NEXT: <array>
|
||||
// CHECK-NEXT: <dict>
|
||||
// CHECK-NEXT: <key>line</key><integer>79</integer>
|
||||
// CHECK-NEXT: <key>col</key><integer>7</integer>
|
||||
// CHECK-NEXT: <key>file</key><integer>0</integer>
|
||||
// CHECK-NEXT: </dict>
|
||||
// CHECK-NEXT: <dict>
|
||||
// CHECK-NEXT: <key>line</key><integer>79</integer>
|
||||
// CHECK-NEXT: <key>col</key><integer>11</integer>
|
||||
// CHECK-NEXT: <key>file</key><integer>0</integer>
|
||||
// CHECK-NEXT: </dict>
|
||||
// CHECK-NEXT: </array>
|
||||
// CHECK-NEXT: </array>
|
||||
// CHECK-NEXT: <key>depth</key><integer>0</integer>
|
||||
// CHECK-NEXT: <key>extended_message</key>
|
||||
// CHECK-NEXT: <string>Assuming the condition is true</string>
|
||||
// CHECK-NEXT: <key>message</key>
|
||||
// CHECK-NEXT: <string>Assuming the condition is true</string>
|
||||
// CHECK-NEXT: </dict>
|
||||
// CHECK-NEXT: <dict>
|
||||
// CHECK-NEXT: <key>kind</key><string>control</string>
|
||||
// CHECK-NEXT: <key>edges</key>
|
||||
// CHECK-NEXT: <array>
|
||||
// CHECK-NEXT: <dict>
|
||||
// CHECK-NEXT: <key>start</key>
|
||||
// CHECK-NEXT: <array>
|
||||
// CHECK-NEXT: <dict>
|
||||
// CHECK-NEXT: <key>line</key><integer>79</integer>
|
||||
// CHECK-NEXT: <key>col</key><integer>7</integer>
|
||||
// CHECK-NEXT: <key>file</key><integer>0</integer>
|
||||
// CHECK-NEXT: </dict>
|
||||
// CHECK-NEXT: <dict>
|
||||
// CHECK-NEXT: <key>line</key><integer>79</integer>
|
||||
// CHECK-NEXT: <key>col</key><integer>7</integer>
|
||||
// CHECK-NEXT: <key>file</key><integer>0</integer>
|
||||
// CHECK-NEXT: </dict>
|
||||
// CHECK-NEXT: </array>
|
||||
// CHECK-NEXT: <key>end</key>
|
||||
// CHECK-NEXT: <array>
|
||||
// CHECK-NEXT: <dict>
|
||||
// CHECK-NEXT: <key>line</key><integer>82</integer>
|
||||
// CHECK-NEXT: <key>line</key><integer>81</integer>
|
||||
// CHECK-NEXT: <key>col</key><integer>5</integer>
|
||||
// CHECK-NEXT: <key>file</key><integer>0</integer>
|
||||
// CHECK-NEXT: </dict>
|
||||
// CHECK-NEXT: <dict>
|
||||
// CHECK-NEXT: <key>line</key><integer>82</integer>
|
||||
// CHECK-NEXT: <key>line</key><integer>81</integer>
|
||||
// CHECK-NEXT: <key>col</key><integer>5</integer>
|
||||
// CHECK-NEXT: <key>file</key><integer>0</integer>
|
||||
// CHECK-NEXT: </dict>
|
||||
|
@ -1658,12 +1594,12 @@ void testNonDiagnosableBranchArithmetic(int a, int b) {
|
|||
// CHECK-NEXT: <key>start</key>
|
||||
// CHECK-NEXT: <array>
|
||||
// CHECK-NEXT: <dict>
|
||||
// CHECK-NEXT: <key>line</key><integer>82</integer>
|
||||
// CHECK-NEXT: <key>line</key><integer>81</integer>
|
||||
// CHECK-NEXT: <key>col</key><integer>5</integer>
|
||||
// CHECK-NEXT: <key>file</key><integer>0</integer>
|
||||
// CHECK-NEXT: </dict>
|
||||
// CHECK-NEXT: <dict>
|
||||
// CHECK-NEXT: <key>line</key><integer>82</integer>
|
||||
// CHECK-NEXT: <key>line</key><integer>81</integer>
|
||||
// CHECK-NEXT: <key>col</key><integer>5</integer>
|
||||
// CHECK-NEXT: <key>file</key><integer>0</integer>
|
||||
// CHECK-NEXT: </dict>
|
||||
|
@ -1671,12 +1607,12 @@ void testNonDiagnosableBranchArithmetic(int a, int b) {
|
|||
// CHECK-NEXT: <key>end</key>
|
||||
// CHECK-NEXT: <array>
|
||||
// CHECK-NEXT: <dict>
|
||||
// CHECK-NEXT: <key>line</key><integer>82</integer>
|
||||
// CHECK-NEXT: <key>line</key><integer>81</integer>
|
||||
// CHECK-NEXT: <key>col</key><integer>24</integer>
|
||||
// CHECK-NEXT: <key>file</key><integer>0</integer>
|
||||
// CHECK-NEXT: </dict>
|
||||
// CHECK-NEXT: <dict>
|
||||
// CHECK-NEXT: <key>line</key><integer>82</integer>
|
||||
// CHECK-NEXT: <key>line</key><integer>81</integer>
|
||||
// CHECK-NEXT: <key>col</key><integer>24</integer>
|
||||
// CHECK-NEXT: <key>file</key><integer>0</integer>
|
||||
// CHECK-NEXT: </dict>
|
||||
|
@ -1688,7 +1624,7 @@ void testNonDiagnosableBranchArithmetic(int a, int b) {
|
|||
// CHECK-NEXT: <key>kind</key><string>event</string>
|
||||
// CHECK-NEXT: <key>location</key>
|
||||
// CHECK-NEXT: <dict>
|
||||
// CHECK-NEXT: <key>line</key><integer>82</integer>
|
||||
// CHECK-NEXT: <key>line</key><integer>81</integer>
|
||||
// CHECK-NEXT: <key>col</key><integer>24</integer>
|
||||
// CHECK-NEXT: <key>file</key><integer>0</integer>
|
||||
// CHECK-NEXT: </dict>
|
||||
|
@ -1696,12 +1632,12 @@ void testNonDiagnosableBranchArithmetic(int a, int b) {
|
|||
// CHECK-NEXT: <array>
|
||||
// CHECK-NEXT: <array>
|
||||
// CHECK-NEXT: <dict>
|
||||
// CHECK-NEXT: <key>line</key><integer>82</integer>
|
||||
// CHECK-NEXT: <key>line</key><integer>81</integer>
|
||||
// CHECK-NEXT: <key>col</key><integer>5</integer>
|
||||
// CHECK-NEXT: <key>file</key><integer>0</integer>
|
||||
// CHECK-NEXT: </dict>
|
||||
// CHECK-NEXT: <dict>
|
||||
// CHECK-NEXT: <key>line</key><integer>82</integer>
|
||||
// CHECK-NEXT: <key>line</key><integer>81</integer>
|
||||
// CHECK-NEXT: <key>col</key><integer>26</integer>
|
||||
// CHECK-NEXT: <key>file</key><integer>0</integer>
|
||||
// CHECK-NEXT: </dict>
|
||||
|
@ -1722,10 +1658,10 @@ void testNonDiagnosableBranchArithmetic(int a, int b) {
|
|||
// CHECK-NEXT: <key>issue_hash_content_of_line_in_context</key><string>f56671e5f67c73abef619b56f7c29fa4</string>
|
||||
// CHECK-NEXT: <key>issue_context_kind</key><string>function</string>
|
||||
// CHECK-NEXT: <key>issue_context</key><string>testNonDiagnosableBranchArithmetic</string>
|
||||
// CHECK-NEXT: <key>issue_hash_function_offset</key><string>4</string>
|
||||
// CHECK-NEXT: <key>issue_hash_function_offset</key><string>3</string>
|
||||
// CHECK-NEXT: <key>location</key>
|
||||
// CHECK-NEXT: <dict>
|
||||
// CHECK-NEXT: <key>line</key><integer>82</integer>
|
||||
// CHECK-NEXT: <key>line</key><integer>81</integer>
|
||||
// CHECK-NEXT: <key>col</key><integer>24</integer>
|
||||
// CHECK-NEXT: <key>file</key><integer>0</integer>
|
||||
// CHECK-NEXT: </dict>
|
||||
|
|
|
@ -69,7 +69,7 @@ void test_4(int x, int y) {
|
|||
static int stat;
|
||||
clang_analyzer_explain(x + 1); // expected-warning-re{{{{^\(argument 'x'\) \+ 1$}}}}
|
||||
clang_analyzer_explain(1 + y); // expected-warning-re{{{{^\(argument 'y'\) \+ 1$}}}}
|
||||
clang_analyzer_explain(x + y); // expected-warning-re{{{{^\(argument 'x'\) \+ \(argument 'y'\)$}}}}
|
||||
clang_analyzer_explain(x + y); // expected-warning-re{{{{^unknown value$}}}}
|
||||
clang_analyzer_explain(z); // expected-warning-re{{{{^undefined value$}}}}
|
||||
clang_analyzer_explain(&z); // expected-warning-re{{{{^pointer to local variable 'z'$}}}}
|
||||
clang_analyzer_explain(stat); // expected-warning-re{{{{^signed 32-bit integer '0'$}}}}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,7 +1,7 @@
|
|||
// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix -analyzer-eagerly-assume -verify %s
|
||||
// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix -analyzer-eagerly-assume -analyzer-output=plist-multi-file -analyzer-config path-diagnostics-alternate=true %s -o %t.plist
|
||||
// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix -analyzer-eagerly-assume -analyzer-output=plist-multi-file -analyzer-config path-diagnostics-alternate=ture %s -o %t.plist
|
||||
// RUN: FileCheck --input-file=%t.plist %s
|
||||
// REQUIRES: !z3
|
||||
|
||||
|
||||
typedef __typeof(sizeof(int)) size_t;
|
||||
void *malloc(size_t);
|
||||
|
@ -11,13 +11,13 @@ void noteOnMacro(int y) {
|
|||
y++;
|
||||
y--;
|
||||
mallocmemory
|
||||
y++;
|
||||
y++;
|
||||
y++;
|
||||
delete x; // expected-warning {{Memory allocated by malloc() should be deallocated by free(), not 'delete'}}
|
||||
}
|
||||
|
||||
void macroIsFirstInFunction(int y) {
|
||||
mallocmemory
|
||||
mallocmemory
|
||||
y++; // expected-warning {{Potential leak of memory pointed to by 'x'}}
|
||||
}
|
||||
|
||||
|
@ -39,7 +39,7 @@ int macroInExpressionNoNote(int *p, int y) {;
|
|||
return *p; // expected-warning {{Dereference of null pointer}}
|
||||
}
|
||||
|
||||
#define macroWithArg(mp) mp==0
|
||||
#define macroWithArg(mp) mp==0
|
||||
int macroWithArgInExpression(int *p, int y) {;
|
||||
y++;
|
||||
if (macroWithArg(p))
|
||||
|
@ -85,7 +85,6 @@ void test1() {
|
|||
void test2(int *p) {
|
||||
CALL_FN(p);
|
||||
}
|
||||
|
||||
// CHECK: <key>diagnostics</key>
|
||||
// CHECK-NEXT: <array>
|
||||
// CHECK-NEXT: <dict>
|
||||
|
@ -637,69 +636,6 @@ void test2(int *p) {
|
|||
// CHECK-NEXT: <key>end</key>
|
||||
// CHECK-NEXT: <array>
|
||||
// CHECK-NEXT: <dict>
|
||||
// CHECK-NEXT: <key>line</key><integer>36</integer>
|
||||
// CHECK-NEXT: <key>col</key><integer>7</integer>
|
||||
// CHECK-NEXT: <key>file</key><integer>0</integer>
|
||||
// CHECK-NEXT: </dict>
|
||||
// CHECK-NEXT: <dict>
|
||||
// CHECK-NEXT: <key>line</key><integer>36</integer>
|
||||
// CHECK-NEXT: <key>col</key><integer>7</integer>
|
||||
// CHECK-NEXT: <key>file</key><integer>0</integer>
|
||||
// CHECK-NEXT: </dict>
|
||||
// CHECK-NEXT: </array>
|
||||
// CHECK-NEXT: </dict>
|
||||
// CHECK-NEXT: </array>
|
||||
// CHECK-NEXT: </dict>
|
||||
// CHECK-NEXT: <dict>
|
||||
// CHECK-NEXT: <key>kind</key><string>event</string>
|
||||
// CHECK-NEXT: <key>location</key>
|
||||
// CHECK-NEXT: <dict>
|
||||
// CHECK-NEXT: <key>line</key><integer>36</integer>
|
||||
// CHECK-NEXT: <key>col</key><integer>7</integer>
|
||||
// CHECK-NEXT: <key>file</key><integer>0</integer>
|
||||
// CHECK-NEXT: </dict>
|
||||
// CHECK-NEXT: <key>ranges</key>
|
||||
// CHECK-NEXT: <array>
|
||||
// CHECK-NEXT: <array>
|
||||
// CHECK-NEXT: <dict>
|
||||
// CHECK-NEXT: <key>line</key><integer>36</integer>
|
||||
// CHECK-NEXT: <key>col</key><integer>7</integer>
|
||||
// CHECK-NEXT: <key>file</key><integer>0</integer>
|
||||
// CHECK-NEXT: </dict>
|
||||
// CHECK-NEXT: <dict>
|
||||
// CHECK-NEXT: <key>line</key><integer>36</integer>
|
||||
// CHECK-NEXT: <key>col</key><integer>25</integer>
|
||||
// CHECK-NEXT: <key>file</key><integer>0</integer>
|
||||
// CHECK-NEXT: </dict>
|
||||
// CHECK-NEXT: </array>
|
||||
// CHECK-NEXT: </array>
|
||||
// CHECK-NEXT: <key>depth</key><integer>0</integer>
|
||||
// CHECK-NEXT: <key>extended_message</key>
|
||||
// CHECK-NEXT: <string>Assuming the condition is true</string>
|
||||
// CHECK-NEXT: <key>message</key>
|
||||
// CHECK-NEXT: <string>Assuming the condition is true</string>
|
||||
// CHECK-NEXT: </dict>
|
||||
// CHECK-NEXT: <dict>
|
||||
// CHECK-NEXT: <key>kind</key><string>control</string>
|
||||
// CHECK-NEXT: <key>edges</key>
|
||||
// CHECK-NEXT: <array>
|
||||
// CHECK-NEXT: <dict>
|
||||
// CHECK-NEXT: <key>start</key>
|
||||
// CHECK-NEXT: <array>
|
||||
// CHECK-NEXT: <dict>
|
||||
// CHECK-NEXT: <key>line</key><integer>36</integer>
|
||||
// CHECK-NEXT: <key>col</key><integer>7</integer>
|
||||
// CHECK-NEXT: <key>file</key><integer>0</integer>
|
||||
// CHECK-NEXT: </dict>
|
||||
// CHECK-NEXT: <dict>
|
||||
// CHECK-NEXT: <key>line</key><integer>36</integer>
|
||||
// CHECK-NEXT: <key>col</key><integer>7</integer>
|
||||
// CHECK-NEXT: <key>file</key><integer>0</integer>
|
||||
// CHECK-NEXT: </dict>
|
||||
// CHECK-NEXT: </array>
|
||||
// CHECK-NEXT: <key>end</key>
|
||||
// CHECK-NEXT: <array>
|
||||
// CHECK-NEXT: <dict>
|
||||
// CHECK-NEXT: <key>line</key><integer>37</integer>
|
||||
// CHECK-NEXT: <key>col</key><integer>5</integer>
|
||||
// CHECK-NEXT: <key>file</key><integer>0</integer>
|
||||
|
|
|
@ -67,8 +67,8 @@ void f7(long foo)
|
|||
{
|
||||
unsigned index = -1;
|
||||
if (index < foo) index = foo;
|
||||
if (index - 1 == 0)
|
||||
clang_analyzer_warnIfReached(); // no-warning
|
||||
if (index - 1 == 0) // Was not reached prior fix.
|
||||
clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
|
||||
else
|
||||
clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
|
||||
}
|
||||
|
@ -87,8 +87,8 @@ void f9(long foo)
|
|||
{
|
||||
unsigned index = -1;
|
||||
if (index < foo) index = foo;
|
||||
if (index - 1L == 0L)
|
||||
clang_analyzer_warnIfReached(); // no-warning
|
||||
if (index - 1L == 0L) // Was not reached prior fix.
|
||||
clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
|
||||
else
|
||||
clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
|
||||
}
|
||||
|
@ -117,8 +117,8 @@ void f12(long foo)
|
|||
{
|
||||
unsigned index = -1;
|
||||
if (index < foo) index = foo;
|
||||
if (index - 1UL == 0L)
|
||||
clang_analyzer_warnIfReached(); // no-warning
|
||||
if (index - 1UL == 0L) // Was not reached prior fix.
|
||||
clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
|
||||
else
|
||||
clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
|
||||
}
|
||||
|
|
|
@ -57,7 +57,8 @@ void test_fread_fwrite(FILE *fp, int *buf) {
|
|||
size_t y = fread(buf, sizeof(int), 10, fp);
|
||||
clang_analyzer_eval(y <= 10); // expected-warning{{TRUE}}
|
||||
size_t z = fwrite(buf, sizeof(int), y, fp);
|
||||
clang_analyzer_eval(z <= y); // expected-warning{{TRUE}}
|
||||
// FIXME: should be TRUE once symbol-symbol constraint support is improved.
|
||||
clang_analyzer_eval(z <= y); // expected-warning{{UNKNOWN}}
|
||||
}
|
||||
|
||||
ssize_t getline(char **, size_t *, FILE *);
|
||||
|
|
Loading…
Reference in New Issue