summaryrefslogtreecommitdiffstats
path: root/clang/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
diff options
context:
space:
mode:
authorGeorge Karpenkov <ekarpenkov@apple.com>2019-01-10 18:14:51 +0000
committerGeorge Karpenkov <ekarpenkov@apple.com>2019-01-10 18:14:51 +0000
commit371bfd729515bc0973afc153ffaa891b060b5a48 (patch)
tree412498138f29e0aba4f3388d482d93a10f57d2af /clang/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
parent4cb992e2541027caa9431d4ce3114ab35651d94b (diff)
downloadbcm5719-llvm-371bfd729515bc0973afc153ffaa891b060b5a48.tar.gz
bcm5719-llvm-371bfd729515bc0973afc153ffaa891b060b5a48.zip
[analyzer] [RetainCountChecker] [NFC] Refactor the way attributes are handled
Make sure all checks for attributes go through a centralized function, which checks whether attribute handling is enabled, and performs validation. The type of the attribute is returned. Sadly, metaprogramming is required as attributes have no sensible static getters. Differential Revision: https://reviews.llvm.org/D56222 llvm-svn: 350862
Diffstat (limited to 'clang/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp')
-rw-r--r--clang/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp186
1 files changed, 103 insertions, 83 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp b/clang/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
index 51fa760ab55..a0fe2fefde8 100644
--- a/clang/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
+++ b/clang/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
@@ -36,17 +36,79 @@ constexpr static bool isOneOf() {
return std::is_same<T, P>::value || isOneOf<T, ToCompare...>();
}
-template <class T> bool RetainSummaryManager::isAttrEnabled() {
+namespace {
+
+struct GeneralizedReturnsRetainedAttr {
+ static bool classof(const Attr *A) {
+ if (auto AA = dyn_cast<AnnotateAttr>(A))
+ return AA->getAnnotation() == "rc_ownership_returns_retained";
+ return false;
+ }
+};
+
+struct GeneralizedReturnsNotRetainedAttr {
+ static bool classof(const Attr *A) {
+ if (auto AA = dyn_cast<AnnotateAttr>(A))
+ return AA->getAnnotation() == "rc_ownership_returns_not_retained";
+ return false;
+ }
+};
+
+struct GeneralizedConsumedAttr {
+ static bool classof(const Attr *A) {
+ if (auto AA = dyn_cast<AnnotateAttr>(A))
+ return AA->getAnnotation() == "rc_ownership_consumed";
+ return false;
+ }
+};
+
+}
+
+template <class T>
+Optional<ObjKind> RetainSummaryManager::hasAnyEnabledAttrOf(const Decl *D,
+ QualType QT) {
+ ObjKind K;
if (isOneOf<T, CFConsumedAttr, CFReturnsRetainedAttr,
- CFReturnsNotRetainedAttr, NSConsumedAttr, NSConsumesSelfAttr,
- NSReturnsAutoreleasedAttr, NSReturnsRetainedAttr,
- NSReturnsNotRetainedAttr>()) {
- return TrackObjCAndCFObjects;
+ CFReturnsNotRetainedAttr>()) {
+ if (!TrackObjCAndCFObjects)
+ return None;
+
+ K = ObjKind::CF;
+ } else if (isOneOf<T, NSConsumedAttr, NSConsumesSelfAttr,
+ NSReturnsAutoreleasedAttr, NSReturnsRetainedAttr,
+ NSReturnsNotRetainedAttr, NSConsumesSelfAttr>()) {
+
+ if (!TrackObjCAndCFObjects)
+ return None;
+
+ if (isOneOf<T, NSReturnsRetainedAttr, NSReturnsAutoreleasedAttr,
+ NSReturnsNotRetainedAttr>() &&
+ !cocoa::isCocoaObjectRef(QT))
+ return None;
+ K = ObjKind::ObjC;
} else if (isOneOf<T, OSConsumedAttr, OSConsumesThisAttr,
OSReturnsNotRetainedAttr, OSReturnsRetainedAttr>()) {
- return TrackOSObjects;
+ if (!TrackOSObjects)
+ return None;
+ K = ObjKind::OS;
+ } else if (isOneOf<T, GeneralizedReturnsNotRetainedAttr,
+ GeneralizedReturnsRetainedAttr,
+ GeneralizedConsumedAttr>()) {
+ K = ObjKind::Generalized;
+ } else {
+ llvm_unreachable("Unexpected attribute");
}
- llvm_unreachable("Unexpected attribute passed");
+ if (D->hasAttr<T>())
+ return K;
+ return None;
+}
+
+template <class T1, class T2, class... Others>
+Optional<ObjKind> RetainSummaryManager::hasAnyEnabledAttrOf(const Decl *D,
+ QualType QT) {
+ if (auto Out = hasAnyEnabledAttrOf<T1>(D, QT))
+ return Out;
+ return hasAnyEnabledAttrOf<T2, Others...>(D, QT);
}
const RetainSummary *
@@ -727,33 +789,18 @@ RetainSummaryManager::getCFSummaryGetRule(const FunctionDecl *FD) {
Optional<RetEffect>
RetainSummaryManager::getRetEffectFromAnnotations(QualType RetTy,
const Decl *D) {
- if (TrackObjCAndCFObjects && cocoa::isCocoaObjectRef(RetTy)) {
- if (D->hasAttr<NSReturnsRetainedAttr>())
- return ObjCAllocRetE;
-
- if (D->hasAttr<NSReturnsNotRetainedAttr>() ||
- D->hasAttr<NSReturnsAutoreleasedAttr>())
- return RetEffect::MakeNotOwned(ObjKind::ObjC);
-
- } else if (!RetTy->isPointerType()) {
- return None;
- }
+ if (hasAnyEnabledAttrOf<NSReturnsRetainedAttr>(D, RetTy))
+ return ObjCAllocRetE;
- if (hasEnabledAttr<CFReturnsRetainedAttr>(D)) {
- return RetEffect::MakeOwned(ObjKind::CF);
- } else if (hasEnabledAttr<OSReturnsRetainedAttr>(D)) {
- return RetEffect::MakeOwned(ObjKind::OS);
- } else if (hasRCAnnotation(D, "rc_ownership_returns_retained")) {
- return RetEffect::MakeOwned(ObjKind::Generalized);
- }
+ if (auto K = hasAnyEnabledAttrOf<CFReturnsRetainedAttr, OSReturnsRetainedAttr,
+ GeneralizedReturnsRetainedAttr>(D, RetTy))
+ return RetEffect::MakeOwned(*K);
- if (hasEnabledAttr<CFReturnsNotRetainedAttr>(D)) {
- return RetEffect::MakeNotOwned(ObjKind::CF);
- } else if (hasEnabledAttr<OSReturnsNotRetainedAttr>(D)) {
- return RetEffect::MakeNotOwned(ObjKind::OS);
- } else if (hasRCAnnotation(D, "rc_ownership_returns_not_retained")) {
- return RetEffect::MakeNotOwned(ObjKind::Generalized);
- }
+ if (auto K = hasAnyEnabledAttrOf<
+ CFReturnsNotRetainedAttr, OSReturnsNotRetainedAttr,
+ GeneralizedReturnsNotRetainedAttr, NSReturnsNotRetainedAttr,
+ NSReturnsAutoreleasedAttr>(D, RetTy))
+ return RetEffect::MakeNotOwned(*K);
if (const auto *MD = dyn_cast<CXXMethodDecl>(D))
for (const auto *PD : MD->overridden_methods())
@@ -766,37 +813,20 @@ RetainSummaryManager::getRetEffectFromAnnotations(QualType RetTy,
bool RetainSummaryManager::applyFunctionParamAnnotationEffect(
const ParmVarDecl *pd, unsigned parm_idx, const FunctionDecl *FD,
RetainSummaryTemplate &Template) {
- if (hasEnabledAttr<NSConsumedAttr>(pd)) {
- Template->addArg(AF, parm_idx, ArgEffect(DecRef, ObjKind::ObjC));
+ QualType QT = pd->getType();
+ if (auto K =
+ hasAnyEnabledAttrOf<NSConsumedAttr, CFConsumedAttr, OSConsumedAttr,
+ GeneralizedConsumedAttr>(pd, QT)) {
+ Template->addArg(AF, parm_idx, ArgEffect(DecRef, *K));
return true;
- } else if (hasEnabledAttr<CFConsumedAttr>(pd)) {
- Template->addArg(AF, parm_idx, ArgEffect(DecRef, ObjKind::CF));
+ } else if (auto K =
+ hasAnyEnabledAttrOf<CFReturnsRetainedAttr,
+ GeneralizedReturnsRetainedAttr>(pd, QT)) {
+ Template->addArg(AF, parm_idx, ArgEffect(RetainedOutParameter, *K));
return true;
- } else if (hasEnabledAttr<OSConsumedAttr>(pd)) {
- Template->addArg(AF, parm_idx, ArgEffect(DecRef, ObjKind::OS));
+ } else if (auto K = hasAnyEnabledAttrOf<CFReturnsNotRetainedAttr>(pd, QT)) {
+ Template->addArg(AF, parm_idx, ArgEffect(UnretainedOutParameter, *K));
return true;
- } else if (hasRCAnnotation(pd, "rc_ownership_consumed")) {
- Template->addArg(AF, parm_idx, ArgEffect(DecRef, ObjKind::Generalized));
- return true;
- } else if (hasEnabledAttr<CFReturnsRetainedAttr>(pd) ||
- hasRCAnnotation(pd, "rc_ownership_returns_retained")) {
- QualType PointeeTy = pd->getType()->getPointeeType();
- if (!PointeeTy.isNull()) {
- if (coreFoundation::isCFObjectRef(PointeeTy)) {
- Template->addArg(AF, parm_idx, ArgEffect(RetainedOutParameter,
- ObjKind::CF));
- return true;
- }
- }
- } else if (hasEnabledAttr<CFReturnsNotRetainedAttr>(pd)) {
- QualType PointeeTy = pd->getType()->getPointeeType();
- if (!PointeeTy.isNull()) {
- if (coreFoundation::isCFObjectRef(PointeeTy)) {
- Template->addArg(AF, parm_idx, ArgEffect(UnretainedOutParameter,
- ObjKind::CF));
- return true;
- }
- }
} else {
if (const auto *MD = dyn_cast<CXXMethodDecl>(FD)) {
for (const auto *OD : MD->overridden_methods()) {
@@ -831,7 +861,7 @@ RetainSummaryManager::updateSummaryFromAnnotations(const RetainSummary *&Summ,
if (Optional<RetEffect> RetE = getRetEffectFromAnnotations(RetTy, FD))
Template->setRetEffect(*RetE);
- if (hasEnabledAttr<OSConsumesThisAttr>(FD))
+ if (hasAnyEnabledAttrOf<OSConsumesThisAttr>(FD, RetTy))
Template->setThisEffect(ArgEffect(DecRef, ObjKind::OS));
}
@@ -845,35 +875,25 @@ RetainSummaryManager::updateSummaryFromAnnotations(const RetainSummary *&Summ,
RetainSummaryTemplate Template(Summ, *this);
// Effects on the receiver.
- if (MD->hasAttr<NSConsumesSelfAttr>())
+ if (hasAnyEnabledAttrOf<NSConsumesSelfAttr>(MD, MD->getReturnType()))
Template->setReceiverEffect(ArgEffect(DecRef, ObjKind::ObjC));
// Effects on the parameters.
unsigned parm_idx = 0;
- for (auto pi=MD->param_begin(), pe=MD->param_end();
- pi != pe; ++pi, ++parm_idx) {
+ for (auto pi = MD->param_begin(), pe = MD->param_end(); pi != pe;
+ ++pi, ++parm_idx) {
const ParmVarDecl *pd = *pi;
- if (pd->hasAttr<NSConsumedAttr>()) {
- Template->addArg(AF, parm_idx, ArgEffect(DecRef, ObjKind::ObjC));
- } else if (pd->hasAttr<CFConsumedAttr>()) {
- Template->addArg(AF, parm_idx, ArgEffect(DecRef, ObjKind::CF));
- } else if (pd->hasAttr<OSConsumedAttr>()) {
- Template->addArg(AF, parm_idx, ArgEffect(DecRef, ObjKind::OS));
- } else if (pd->hasAttr<CFReturnsRetainedAttr>()) {
- QualType PointeeTy = pd->getType()->getPointeeType();
- if (!PointeeTy.isNull())
- if (coreFoundation::isCFObjectRef(PointeeTy))
- Template->addArg(AF, parm_idx,
- ArgEffect(RetainedOutParameter, ObjKind::CF));
- } else if (pd->hasAttr<CFReturnsNotRetainedAttr>()) {
- QualType PointeeTy = pd->getType()->getPointeeType();
- if (!PointeeTy.isNull())
- if (coreFoundation::isCFObjectRef(PointeeTy))
- Template->addArg(AF, parm_idx, ArgEffect(UnretainedOutParameter,
- ObjKind::CF));
+ QualType QT = pd->getType();
+ if (auto K =
+ hasAnyEnabledAttrOf<NSConsumedAttr, CFConsumedAttr, OSConsumedAttr>(
+ pd, QT)) {
+ Template->addArg(AF, parm_idx, ArgEffect(DecRef, *K));
+ } else if (auto K = hasAnyEnabledAttrOf<CFReturnsRetainedAttr>(pd, QT)) {
+ Template->addArg(AF, parm_idx, ArgEffect(RetainedOutParameter, *K));
+ } else if (auto K = hasAnyEnabledAttrOf<CFReturnsNotRetainedAttr>(pd, QT)) {
+ Template->addArg(AF, parm_idx, ArgEffect(UnretainedOutParameter, *K));
}
}
-
QualType RetTy = MD->getReturnType();
if (Optional<RetEffect> RetE = getRetEffectFromAnnotations(RetTy, MD))
Template->setRetEffect(*RetE);
OpenPOWER on IntegriCloud