summaryrefslogtreecommitdiffstats
path: root/clang/lib/StaticAnalyzer/Checkers
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/StaticAnalyzer/Checkers')
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp28
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h14
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.h3
3 files changed, 33 insertions, 12 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
index a72f09fb3ca..dc8609f889e 100644
--- a/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "RetainCountChecker.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
using namespace clang;
using namespace ento;
@@ -326,6 +327,31 @@ void RetainCountChecker::checkPostStmt(const ObjCIvarRefExpr *IRE,
C.addTransition(State);
}
+static bool isReceiverUnconsumedSelf(const CallEvent &Call) {
+ if (const auto *MC = dyn_cast<ObjCMethodCall>(&Call)) {
+
+ // Check if the message is not consumed, we know it will not be used in
+ // an assignment, ex: "self = [super init]".
+ return MC->getMethodFamily() == OMF_init && MC->isReceiverSelfOrSuper() &&
+ !Call.getLocationContext()
+ ->getAnalysisDeclContext()
+ ->getParentMap()
+ .isConsumedExpr(Call.getOriginExpr());
+ }
+ return false;
+}
+
+const static RetainSummary *getSummary(RetainSummaryManager &Summaries,
+ const CallEvent &Call,
+ QualType ReceiverType) {
+ const Expr *CE = Call.getOriginExpr();
+ AnyCall C =
+ CE ? *AnyCall::forExpr(CE)
+ : AnyCall::forDestructorCall(cast<CXXDestructorDecl>(Call.getDecl()));
+ return Summaries.getSummary(C, Call.hasNonZeroCallbackArg(),
+ isReceiverUnconsumedSelf(Call), ReceiverType);
+}
+
void RetainCountChecker::checkPostCall(const CallEvent &Call,
CheckerContext &C) const {
RetainSummaryManager &Summaries = getSummaryManager(C);
@@ -341,7 +367,7 @@ void RetainCountChecker::checkPostCall(const CallEvent &Call,
}
}
- const RetainSummary *Summ = Summaries.getSummary(Call, ReceiverType);
+ const RetainSummary *Summ = getSummary(Summaries, Call, ReceiverType);
if (C.wasInlined) {
processSummaryOfInlined(*Summ, Call, C);
diff --git a/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h b/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h
index 8e74f6cbb0d..775cd21851d 100644
--- a/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h
+++ b/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h
@@ -21,6 +21,7 @@
#include "clang/AST/DeclObjC.h"
#include "clang/AST/ParentMap.h"
#include "clang/Analysis/DomainSpecific/CocoaConventions.h"
+#include "clang/Analysis/RetainSummaryManager.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Analysis/SelectorExtras.h"
@@ -32,7 +33,6 @@
#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h"
-#include "clang/StaticAnalyzer/Core/RetainSummaryManager.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/ImmutableList.h"
@@ -275,15 +275,9 @@ public:
RetainCountChecker() {};
RetainSummaryManager &getSummaryManager(ASTContext &Ctx) const {
- // FIXME: We don't support ARC being turned on and off during one analysis.
- // (nor, for that matter, do we support changing ASTContexts)
- bool ARCEnabled = (bool)Ctx.getLangOpts().ObjCAutoRefCount;
- if (!Summaries) {
- Summaries.reset(new RetainSummaryManager(
- Ctx, ARCEnabled, TrackObjCAndCFObjects, TrackOSObjects));
- } else {
- assert(Summaries->isARCEnabled() == ARCEnabled);
- }
+ if (!Summaries)
+ Summaries.reset(
+ new RetainSummaryManager(Ctx, TrackObjCAndCFObjects, TrackOSObjects));
return *Summaries;
}
diff --git a/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.h b/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.h
index e0b53e4387c..ef3c75f87af 100644
--- a/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.h
+++ b/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.h
@@ -14,10 +14,11 @@
#ifndef LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_RETAINCOUNTCHECKER_DIAGNOSTICS_H
#define LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_RETAINCOUNTCHECKER_DIAGNOSTICS_H
+#include "clang/Analysis/RetainSummaryManager.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h"
#include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h"
-#include "clang/StaticAnalyzer/Core/RetainSummaryManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
namespace clang {
namespace ento {
OpenPOWER on IntegriCloud