r307833 - [analyzer] Support generating and reasoning over more symbolic constraint types
Dominic Chen via cfe-commits
cfe-commits at lists.llvm.org
Wed Jul 12 12:37:57 PDT 2017
Author: ddcc
Date: Wed Jul 12 12:37:57 2017
New Revision: 307833
URL: http://llvm.org/viewvc/llvm-project?rev=307833&view=rev
Log:
[analyzer] Support generating and reasoning over more symbolic constraint types
Summary: Generate more IntSymExpr constraints, perform SVal simplification for IntSymExpr and SymbolCast constraints, and create fully symbolic SymExprs
Reviewers: zaks.anna, dcoughlin, NoQ, xazax.hun
Subscribers: mgorny, cfe-commits
Differential Revision: https://reviews.llvm.org/D28953
Added:
cfe/trunk/test/Analysis/plist-macros-z3.cpp
- copied, changed from r307830, cfe/trunk/test/Analysis/plist-macros.cpp
Modified:
cfe/trunk/include/clang/StaticAnalyzer/Checkers/SValExplainer.h
cfe/trunk/lib/StaticAnalyzer/Core/SValBuilder.cpp
cfe/trunk/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
cfe/trunk/lib/StaticAnalyzer/Core/Z3ConstraintManager.cpp
cfe/trunk/test/Analysis/analyzer_test.py
cfe/trunk/test/Analysis/bitwise-ops.c
cfe/trunk/test/Analysis/bool-assignment.c
cfe/trunk/test/Analysis/conditional-path-notes.c
cfe/trunk/test/Analysis/explain-svals.cpp
cfe/trunk/test/Analysis/plist-macros.cpp
cfe/trunk/test/Analysis/range_casts.c
cfe/trunk/test/Analysis/std-c-library-functions.c
Modified: cfe/trunk/include/clang/StaticAnalyzer/Checkers/SValExplainer.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Checkers/SValExplainer.h?rev=307833&r1=307832&r2=307833&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Checkers/SValExplainer.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Checkers/SValExplainer.h Wed Jul 12 12:37:57 2017
@@ -125,8 +125,14 @@ public:
return OS.str();
}
- // TODO: IntSymExpr doesn't appear in practice.
- // Add the relevant code once it does.
+ 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();
+ }
std::string VisitSymSymExpr(const SymSymExpr *S) {
return "(" + Visit(S->getLHS()) + ") " +
@@ -134,8 +140,10 @@ public:
" (" + Visit(S->getRHS()) + ")";
}
- // TODO: SymbolCast doesn't appear in practice.
- // Add the relevant code once it does.
+ std::string VisitSymbolCast(const SymbolCast *S) {
+ return "cast of type '" + S->getType().getAsString() + "' of " +
+ Visit(S->getOperand());
+ }
std::string VisitSymbolicRegion(const SymbolicRegion *R) {
// Explain 'this' object here.
Modified: cfe/trunk/lib/StaticAnalyzer/Core/SValBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/SValBuilder.cpp?rev=307833&r1=307832&r2=307833&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/SValBuilder.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/SValBuilder.cpp Wed Jul 12 12:37:57 2017
@@ -100,7 +100,7 @@ SValBuilder::getRegionValueSymbolVal(con
if (T->isNullPtrType())
return makeZeroVal(T);
-
+
if (!SymbolManager::canSymbolicate(T))
return UnknownVal();
@@ -354,9 +354,6 @@ SVal SValBuilder::makeSymExprValNN(Progr
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
@@ -364,7 +361,7 @@ SVal SValBuilder::makeSymExprValNN(Progr
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)
Modified: cfe/trunk/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp?rev=307833&r1=307832&r2=307833&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp Wed Jul 12 12:37:57 2017
@@ -669,12 +669,12 @@ SVal SimpleSValBuilder::evalBinOpLL(Prog
// 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()) {
- // We can only build expressions with symbols on the left,
- // so we need a reversible operator.
+ const llvm::APSInt &lVal = lhs.castAs<loc::ConcreteInt>().getValue();
+
+ // Prefer expressions with symbols on the left
if (!BinaryOperator::isComparisonOp(op))
- return UnknownVal();
+ return makeNonLoc(lVal, op, rSym, resultTy);
- const llvm::APSInt &lVal = lhs.castAs<loc::ConcreteInt>().getValue();
op = BinaryOperator::reverseComparisonOp(op);
return makeNonLoc(rSym, op, lVal, resultTy);
}
@@ -994,7 +994,8 @@ const llvm::APSInt *SimpleSValBuilder::g
if (SymbolRef Sym = V.getAsSymbol())
return state->getConstraintManager().getSymVal(state, Sym);
- // FIXME: Add support for SymExprs.
+ // FIXME: Add support for SymExprs in RangeConstraintManager.
+
return nullptr;
}
@@ -1019,8 +1020,11 @@ SVal SimpleSValBuilder::simplifySVal(Pro
return nonloc::SymbolVal(S);
}
- // TODO: Support SymbolCast. Support IntSymExpr when/if we actually
- // start producing them.
+ 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());
+ }
SVal VisitSymIntExpr(const SymIntExpr *S) {
SVal LHS = Visit(S->getLHS());
@@ -1045,6 +1049,11 @@ SVal SimpleSValBuilder::simplifySVal(Pro
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());
@@ -1058,7 +1067,8 @@ SVal SimpleSValBuilder::simplifySVal(Pro
SVal VisitNonLocSymbolVal(nonloc::SymbolVal V) {
// Simplification is much more costly than computing complexity.
// For high complexity, it may be not worth it.
- if (V.getSymbol()->computeComplexity() > 100)
+ // Use a lower bound to avoid recursive blowup, e.g. on PR24184.cpp
+ if (V.getSymbol()->computeComplexity() > 10)
return V;
return Visit(V.getSymbol());
}
Modified: cfe/trunk/lib/StaticAnalyzer/Core/Z3ConstraintManager.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/Z3ConstraintManager.cpp?rev=307833&r1=307832&r2=307833&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/Z3ConstraintManager.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/Z3ConstraintManager.cpp Wed Jul 12 12:37:57 2017
@@ -1034,16 +1034,19 @@ ProgramStateRef Z3ConstraintManager::ass
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);
-
- 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);
+ QualType RTy = isBoolTy ? Ctx.BoolTy : getAPSIntType(From);
+ Z3Expr FromExp =
+ isBoolTy ? Z3Expr::fromAPSInt(From.extend(Ctx.getTypeSize(Ctx.BoolTy)))
+ : Z3Expr::fromAPSInt(From);
// Construct single (in)equality
if (From == To)
@@ -1051,6 +1054,10 @@ ProgramStateRef Z3ConstraintManager::ass
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);
@@ -1058,7 +1065,8 @@ ProgramStateRef Z3ConstraintManager::ass
getZ3BinExpr(Exp, RetTy, InRange ? BO_LE : BO_GT, ToExp, RTy, nullptr);
return assumeZ3Expr(
State, Sym,
- Z3Expr::fromBinOp(LHS, InRange ? BO_LAnd : BO_LOr, RHS, isSignedTy));
+ Z3Expr::fromBinOp(LHS, InRange ? BO_LAnd : BO_LOr, RHS,
+ RetTy->isSignedIntegerOrEnumerationType()));
}
ProgramStateRef Z3ConstraintManager::assumeSymUnsupported(ProgramStateRef State,
@@ -1406,6 +1414,7 @@ void Z3ConstraintManager::doTypeConversi
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()) {
@@ -1468,10 +1477,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()) {
Modified: cfe/trunk/test/Analysis/analyzer_test.py
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/analyzer_test.py?rev=307833&r1=307832&r2=307833&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/analyzer_test.py (original)
+++ cfe/trunk/test/Analysis/analyzer_test.py Wed Jul 12 12:37:57 2017
@@ -1,3 +1,4 @@
+import copy
import lit.formats
import lit.TestRunner
@@ -8,18 +9,21 @@ class AnalyzerTest(lit.formats.ShTest):
results = []
# Parse any test requirements ('REQUIRES: ')
- saved_test = test
+ saved_test = copy.deepcopy(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(
- saved_test, litConfig, '-analyzer-constraints=range'))
+ test, litConfig, '-analyzer-constraints=range'))
- if results[-1].code == lit.Test.FAIL:
+ if results[-1].code != lit.Test.PASS:
return results[-1]
# If z3 backend available, add an additional run line for it
- if test.config.clang_staticanalyzer_z3 == '1':
+ if test.config.clang_staticanalyzer_z3 == '1' and '!z3' not in test.requires:
results.append(self.executeWithAnalyzeSubstitution(
saved_test, litConfig, '-analyzer-constraints=z3 -DANALYZER_CM_Z3'))
Modified: cfe/trunk/test/Analysis/bitwise-ops.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/bitwise-ops.c?rev=307833&r1=307832&r2=307833&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/bitwise-ops.c (original)
+++ cfe/trunk/test/Analysis/bitwise-ops.c Wed Jul 12 12:37:57 2017
@@ -7,10 +7,9 @@ void testPersistentConstraints(int x, in
// Sanity check
CHECK(x); // expected-warning{{TRUE}}
CHECK(x & 1); // 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}}
+
+ CHECK(1 - x); // expected-warning{{TRUE}}
+ CHECK(x & y); // expected-warning{{TRUE}}
}
int testConstantShifts_PR18073(int which) {
@@ -29,4 +28,4 @@ int testConstantShifts_PR18073(int which
default:
return 0;
}
-}
\ No newline at end of file
+}
Modified: cfe/trunk/test/Analysis/bool-assignment.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/bool-assignment.c?rev=307833&r1=307832&r2=307833&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/bool-assignment.c (original)
+++ cfe/trunk/test/Analysis/bool-assignment.c Wed Jul 12 12:37:57 2017
@@ -43,11 +43,7 @@ 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) {
Modified: cfe/trunk/test/Analysis/conditional-path-notes.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/conditional-path-notes.c?rev=307833&r1=307832&r2=307833&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/conditional-path-notes.c (original)
+++ cfe/trunk/test/Analysis/conditional-path-notes.c Wed Jul 12 12:37:57 2017
@@ -77,7 +77,8 @@ void testDiagnosableBranchLogical(int a,
void testNonDiagnosableBranchArithmetic(int a, int b) {
if (a - b) {
- // expected-note at -1 {{Taking true branch}}
+ // expected-note at -1 {{Assuming the condition is true}}
+ // expected-note at -2 {{Taking true branch}}
*(volatile int *)0 = 1; // expected-warning{{Dereference of null pointer}}
// expected-note at -1 {{Dereference of null pointer}}
}
@@ -1573,12 +1574,75 @@ void testNonDiagnosableBranchArithmetic(
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>81</integer>
+// 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>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>81</integer>
+// CHECK-NEXT: <key>line</key><integer>82</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1594,12 +1658,12 @@ void testNonDiagnosableBranchArithmetic(
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>81</integer>
+// CHECK-NEXT: <key>line</key><integer>82</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>81</integer>
+// CHECK-NEXT: <key>line</key><integer>82</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1607,12 +1671,12 @@ void testNonDiagnosableBranchArithmetic(
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>81</integer>
+// CHECK-NEXT: <key>line</key><integer>82</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>81</integer>
+// CHECK-NEXT: <key>line</key><integer>82</integer>
// CHECK-NEXT: <key>col</key><integer>24</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1624,7 +1688,7 @@ void testNonDiagnosableBranchArithmetic(
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>81</integer>
+// CHECK-NEXT: <key>line</key><integer>82</integer>
// CHECK-NEXT: <key>col</key><integer>24</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1632,12 +1696,12 @@ void testNonDiagnosableBranchArithmetic(
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>81</integer>
+// CHECK-NEXT: <key>line</key><integer>82</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>81</integer>
+// CHECK-NEXT: <key>line</key><integer>82</integer>
// CHECK-NEXT: <key>col</key><integer>26</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1658,10 +1722,10 @@ void testNonDiagnosableBranchArithmetic(
// 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>3</string>
+// CHECK-NEXT: <key>issue_hash_function_offset</key><string>4</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>81</integer>
+// CHECK-NEXT: <key>line</key><integer>82</integer>
// CHECK-NEXT: <key>col</key><integer>24</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
Modified: cfe/trunk/test/Analysis/explain-svals.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/explain-svals.cpp?rev=307833&r1=307832&r2=307833&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/explain-svals.cpp (original)
+++ cfe/trunk/test/Analysis/explain-svals.cpp Wed Jul 12 12:37:57 2017
@@ -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{{{{^unknown value$}}}}
+ clang_analyzer_explain(x + y); // expected-warning-re{{{{^\(argument 'x'\) \+ \(argument 'y'\)$}}}}
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'$}}}}
Copied: cfe/trunk/test/Analysis/plist-macros-z3.cpp (from r307830, cfe/trunk/test/Analysis/plist-macros.cpp)
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/plist-macros-z3.cpp?p2=cfe/trunk/test/Analysis/plist-macros-z3.cpp&p1=cfe/trunk/test/Analysis/plist-macros.cpp&r1=307830&r2=307833&rev=307833&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/plist-macros.cpp (original)
+++ cfe/trunk/test/Analysis/plist-macros-z3.cpp Wed Jul 12 12:37:57 2017
@@ -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=ture %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=true %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
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,6 +85,7 @@ void test1() {
void test2(int *p) {
CALL_FN(p);
}
+
// CHECK: <key>diagnostics</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
Modified: cfe/trunk/test/Analysis/plist-macros.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/plist-macros.cpp?rev=307833&r1=307832&r2=307833&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/plist-macros.cpp (original)
+++ cfe/trunk/test/Analysis/plist-macros.cpp Wed Jul 12 12:37:57 2017
@@ -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=ture %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=true %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
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,6 +85,7 @@ void test1() {
void test2(int *p) {
CALL_FN(p);
}
+
// CHECK: <key>diagnostics</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
@@ -633,6 +634,69 @@ void test2(int *p) {
// 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>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>
Modified: cfe/trunk/test/Analysis/range_casts.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/range_casts.c?rev=307833&r1=307832&r2=307833&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/range_casts.c (original)
+++ cfe/trunk/test/Analysis/range_casts.c Wed Jul 12 12:37:57 2017
@@ -67,8 +67,8 @@ void f7(long foo)
{
unsigned index = -1;
if (index < foo) index = foo;
- if (index - 1 == 0) // Was not reached prior fix.
- clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
+ if (index - 1 == 0)
+ clang_analyzer_warnIfReached(); // no-warning
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) // Was not reached prior fix.
- clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
+ if (index - 1L == 0L)
+ clang_analyzer_warnIfReached(); // no-warning
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) // Was not reached prior fix.
- clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
+ if (index - 1UL == 0L)
+ clang_analyzer_warnIfReached(); // no-warning
else
clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
}
Modified: cfe/trunk/test/Analysis/std-c-library-functions.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/std-c-library-functions.c?rev=307833&r1=307832&r2=307833&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/std-c-library-functions.c (original)
+++ cfe/trunk/test/Analysis/std-c-library-functions.c Wed Jul 12 12:37:57 2017
@@ -57,8 +57,7 @@ void test_fread_fwrite(FILE *fp, int *bu
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);
- // FIXME: should be TRUE once symbol-symbol constraint support is improved.
- clang_analyzer_eval(z <= y); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval(z <= y); // expected-warning{{TRUE}}
}
ssize_t getline(char **, size_t *, FILE *);
More information about the cfe-commits
mailing list