summaryrefslogtreecommitdiffstats
path: root/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp')
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp19
1 files changed, 19 insertions, 0 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
index 1108b090c1b..32f762e1453 100644
--- a/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
@@ -2735,6 +2735,16 @@ static QualType GetReturnType(const Expr *RetE, ASTContext &Ctx) {
return RetTy;
}
+static bool wasSynthesizedProperty(const ObjCMethodCall *Call,
+ ExplodedNode *N) {
+ if (!Call || !Call->getDecl()->isPropertyAccessor())
+ return false;
+
+ CallExitEnd PP = N->getLocation().castAs<CallExitEnd>();
+ const StackFrameContext *Frame = PP.getCalleeContext();
+ return Frame->getAnalysisDeclContext()->isBodyAutosynthesized();
+}
+
// 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.
@@ -2769,6 +2779,15 @@ void RetainCountChecker::processSummaryOfInlined(const RetainSummary &Summ,
SymbolRef Sym = CallOrMsg.getReturnValue().getAsSymbol();
if (Sym)
state = removeRefBinding(state, Sym);
+ } else if (RE.getKind() == RetEffect::NotOwnedSymbol) {
+ if (wasSynthesizedProperty(MsgInvocation, C.getPredecessor())) {
+ // Believe the summary if we synthesized the body and the return value is
+ // untracked. This handles property getters.
+ SymbolRef Sym = CallOrMsg.getReturnValue().getAsSymbol();
+ if (Sym && !getRefBinding(state, Sym))
+ state = setRefBinding(state, Sym, RefVal::makeNotOwned(RE.getObjKind(),
+ Sym->getType()));
+ }
}
C.addTransition(state);
OpenPOWER on IntegriCloud