summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGeorge Karpenkov <ekarpenkov@apple.com>2018-12-21 19:13:40 +0000
committerGeorge Karpenkov <ekarpenkov@apple.com>2018-12-21 19:13:40 +0000
commit255b05820cb9b52099cc14257fcf599d97084650 (patch)
tree01c78a7b638584cf032259174f28e4c8f5e2041c
parent79f0340c5329b2e21ed76c7b14873ce1d5f9ce64 (diff)
downloadbcm5719-llvm-255b05820cb9b52099cc14257fcf599d97084650.tar.gz
bcm5719-llvm-255b05820cb9b52099cc14257fcf599d97084650.zip
Revert "Revert rL349876 from cfe/trunk: [analyzer] Perform escaping in RetainCountChecker on type mismatch even for inlined functions"
This reverts commit b44b33f6e020a2c369da2b0c1d53cd52975f2526. Revert the revert with the fix. llvm-svn: 349939
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp51
-rw-r--r--clang/test/Analysis/osobject-retain-release.cpp8
2 files changed, 36 insertions, 23 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
index 488cf6d3eb8..87c1ad9edb8 100644
--- a/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
@@ -502,6 +502,25 @@ static Optional<RefVal> refValFromRetEffect(RetEffect RE,
return None;
}
+static bool isPointerToObject(QualType QT) {
+ QualType PT = QT->getPointeeType();
+ if (!PT.isNull())
+ if (PT->getAsCXXRecordDecl())
+ return true;
+ return false;
+}
+
+/// Whether the tracked value should be escaped on a given call.
+/// OSObjects are escaped when passed to void * / etc.
+static bool shouldEscapeArgumentOnCall(const CallEvent &CE, unsigned ArgIdx,
+ const RefVal *TrackedValue) {
+ if (TrackedValue->getObjKind() != RetEffect::OS)
+ return false;
+ if (ArgIdx >= CE.parameters().size())
+ return false;
+ return !isPointerToObject(CE.parameters()[ArgIdx]->getType());
+}
+
// We don't always get the exact modeling of the function with regards to the
// retain count checker even when the function is inlined. For example, we need
// to stop tracking the symbols which were marked with StopTrackingHard.
@@ -512,11 +531,16 @@ void RetainCountChecker::processSummaryOfInlined(const RetainSummary &Summ,
// Evaluate the effect of the arguments.
for (unsigned idx = 0, e = CallOrMsg.getNumArgs(); idx != e; ++idx) {
- if (Summ.getArg(idx) == StopTrackingHard) {
- SVal V = CallOrMsg.getArgSVal(idx);
- if (SymbolRef Sym = V.getAsLocSymbol()) {
+ SVal V = CallOrMsg.getArgSVal(idx);
+
+ if (SymbolRef Sym = V.getAsLocSymbol()) {
+ bool ShouldRemoveBinding = Summ.getArg(idx) == StopTrackingHard;
+ if (const RefVal *T = getRefBinding(state, Sym))
+ if (shouldEscapeArgumentOnCall(CallOrMsg, idx, T))
+ ShouldRemoveBinding = true;
+
+ if (ShouldRemoveBinding)
state = removeRefBinding(state, Sym);
- }
}
}
@@ -574,25 +598,6 @@ static ProgramStateRef updateOutParameter(ProgramStateRef State,
return State;
}
-static bool isPointerToObject(QualType QT) {
- QualType PT = QT->getPointeeType();
- if (!PT.isNull())
- if (PT->getAsCXXRecordDecl())
- return true;
- return false;
-}
-
-/// Whether the tracked value should be escaped on a given call.
-/// OSObjects are escaped when passed to void * / etc.
-static bool shouldEscapeArgumentOnCall(const CallEvent &CE, unsigned ArgIdx,
- const RefVal *TrackedValue) {
- if (TrackedValue->getObjKind() != RetEffect::OS)
- return false;
- if (ArgIdx >= CE.parameters().size())
- return false;
- return !isPointerToObject(CE.parameters()[ArgIdx]->getType());
-}
-
void RetainCountChecker::checkSummary(const RetainSummary &Summ,
const CallEvent &CallOrMsg,
CheckerContext &C) const {
diff --git a/clang/test/Analysis/osobject-retain-release.cpp b/clang/test/Analysis/osobject-retain-release.cpp
index 4c23cdc6e08..0e8e49dd83e 100644
--- a/clang/test/Analysis/osobject-retain-release.cpp
+++ b/clang/test/Analysis/osobject-retain-release.cpp
@@ -91,6 +91,7 @@ struct OSMetaClassBase {
};
void escape(void *);
+void escape_with_source(void *p) {}
bool coin();
bool os_consume_violation_two_args(OS_CONSUME OSObject *obj, bool extra) {
@@ -139,6 +140,13 @@ void test_escaping_into_voidstar() {
escape(obj);
}
+void test_escape_has_source() {
+ OSObject *obj = new OSObject;
+ if (obj)
+ escape_with_source((MYTYPE)obj);
+ return;
+}
+
void test_no_infinite_check_recursion(MyArray *arr) {
OSObject *input = new OSObject;
OSObject *o = arr->generateObject(input);
OpenPOWER on IntegriCloud