summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h8
-rw-r--r--clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h18
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp1
-rw-r--r--clang/lib/StaticAnalyzer/Core/SValBuilder.cpp3
-rw-r--r--clang/lib/StaticAnalyzer/Core/SymbolManager.cpp7
-rw-r--r--clang/test/Analysis/string.c17
6 files changed, 41 insertions, 13 deletions
diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
index e4be349c026..9b55b3cc02e 100644
--- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
+++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
@@ -198,9 +198,11 @@ public:
DefinedOrUnknownSVal getDerivedRegionValueSymbolVal(
SymbolRef parentSymbol, const TypedValueRegion *region);
- DefinedSVal getMetadataSymbolVal(
- const void *symbolTag, const MemRegion *region,
- const Expr *expr, QualType type, unsigned count);
+ DefinedSVal getMetadataSymbolVal(const void *symbolTag,
+ const MemRegion *region,
+ const Expr *expr, QualType type,
+ const LocationContext *LCtx,
+ unsigned count);
DefinedSVal getFunctionPointer(const FunctionDecl *func);
diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h
index 087430583e0..f00dce568e3 100644
--- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h
+++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h
@@ -186,15 +186,18 @@ class SymbolMetadata : public SymbolData {
const MemRegion* R;
const Stmt *S;
QualType T;
+ const LocationContext *LCtx;
unsigned Count;
const void *Tag;
public:
SymbolMetadata(SymbolID sym, const MemRegion* r, const Stmt *s, QualType t,
- unsigned count, const void *tag)
- : SymbolData(SymbolMetadataKind, sym), R(r), S(s), T(t), Count(count), Tag(tag) {}
+ const LocationContext *LCtx, unsigned count, const void *tag)
+ : SymbolData(SymbolMetadataKind, sym), R(r), S(s), T(t), LCtx(LCtx),
+ Count(count), Tag(tag) {}
const MemRegion *getRegion() const { return R; }
const Stmt *getStmt() const { return S; }
+ const LocationContext *getLocationContext() const { return LCtx; }
unsigned getCount() const { return Count; }
const void *getTag() const { return Tag; }
@@ -203,18 +206,19 @@ public:
void dumpToStream(raw_ostream &os) const override;
static void Profile(llvm::FoldingSetNodeID& profile, const MemRegion *R,
- const Stmt *S, QualType T, unsigned Count,
- const void *Tag) {
+ const Stmt *S, QualType T, const LocationContext *LCtx,
+ unsigned Count, const void *Tag) {
profile.AddInteger((unsigned) SymbolMetadataKind);
profile.AddPointer(R);
profile.AddPointer(S);
profile.Add(T);
+ profile.AddPointer(LCtx);
profile.AddInteger(Count);
profile.AddPointer(Tag);
}
void Profile(llvm::FoldingSetNodeID& profile) override {
- Profile(profile, R, S, T, Count, Tag);
+ Profile(profile, R, S, T, LCtx, Count, Tag);
}
// Implement isa<T> support.
@@ -435,7 +439,9 @@ public:
/// VisitCount can be used to differentiate regions corresponding to
/// different loop iterations, thus, making the symbol path-dependent.
const SymbolMetadata *getMetadataSymbol(const MemRegion *R, const Stmt *S,
- QualType T, unsigned VisitCount,
+ QualType T,
+ const LocationContext *LCtx,
+ unsigned VisitCount,
const void *SymbolTag = nullptr);
const SymbolCast* getCastSymbol(const SymExpr *Operand,
diff --git a/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
index 1f13dbad6fd..7cdbe88e88f 100644
--- a/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
@@ -685,6 +685,7 @@ SVal CStringChecker::getCStringLengthForRegion(CheckerContext &C,
QualType sizeTy = svalBuilder.getContext().getSizeType();
SVal strLength = svalBuilder.getMetadataSymbolVal(CStringChecker::getTag(),
MR, Ex, sizeTy,
+ C.getLocationContext(),
C.blockCount());
if (!hypothetical) {
diff --git a/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp b/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp
index 72bcdd9ecb0..fe9a6834f6a 100644
--- a/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp
+++ b/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp
@@ -182,11 +182,12 @@ SValBuilder::getConjuredHeapSymbolVal(const Expr *E,
DefinedSVal SValBuilder::getMetadataSymbolVal(const void *symbolTag,
const MemRegion *region,
const Expr *expr, QualType type,
+ const LocationContext *LCtx,
unsigned count) {
assert(SymbolManager::canSymbolicate(type) && "Invalid metadata symbol type");
SymbolRef sym =
- SymMgr.getMetadataSymbol(region, expr, type, count, symbolTag);
+ SymMgr.getMetadataSymbol(region, expr, type, LCtx, count, symbolTag);
if (Loc::isLocType(type))
return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym));
diff --git a/clang/lib/StaticAnalyzer/Core/SymbolManager.cpp b/clang/lib/StaticAnalyzer/Core/SymbolManager.cpp
index b8b4af1179e..6b99ca510be 100644
--- a/clang/lib/StaticAnalyzer/Core/SymbolManager.cpp
+++ b/clang/lib/StaticAnalyzer/Core/SymbolManager.cpp
@@ -216,17 +216,18 @@ SymbolManager::getExtentSymbol(const SubRegion *R) {
return cast<SymbolExtent>(SD);
}
-const SymbolMetadata*
+const SymbolMetadata *
SymbolManager::getMetadataSymbol(const MemRegion* R, const Stmt *S, QualType T,
+ const LocationContext *LCtx,
unsigned Count, const void *SymbolTag) {
llvm::FoldingSetNodeID profile;
- SymbolMetadata::Profile(profile, R, S, T, Count, SymbolTag);
+ SymbolMetadata::Profile(profile, R, S, T, LCtx, Count, SymbolTag);
void *InsertPos;
SymExpr *SD = DataSet.FindNodeOrInsertPos(profile, InsertPos);
if (!SD) {
SD = (SymExpr*) BPAlloc.Allocate<SymbolMetadata>();
- new (SD) SymbolMetadata(SymbolCounter, R, S, T, Count, SymbolTag);
+ new (SD) SymbolMetadata(SymbolCounter, R, S, T, LCtx, Count, SymbolTag);
DataSet.InsertNode(SD, InsertPos);
++SymbolCounter;
}
diff --git a/clang/test/Analysis/string.c b/clang/test/Analysis/string.c
index 2803362ba43..e541219d05a 100644
--- a/clang/test/Analysis/string.c
+++ b/clang/test/Analysis/string.c
@@ -154,6 +154,23 @@ void strlen_liveness(const char *x) {
clang_analyzer_eval(strlen(x) < 5); // expected-warning{{FALSE}}
}
+
+size_t strlenWrapper(const char *str) {
+ return strlen(str);
+}
+
+extern void invalidate(char *s);
+
+void testStrlenCallee() {
+ char str[42];
+ invalidate(str);
+ size_t lenBefore = strlenWrapper(str);
+ invalidate(str);
+ size_t lenAfter = strlenWrapper(str);
+ clang_analyzer_eval(lenBefore == lenAfter); // expected-warning{{UNKNOWN}}
+}
+
+
//===----------------------------------------------------------------------===
// strnlen()
//===----------------------------------------------------------------------===
OpenPOWER on IntegriCloud