Skip to content

Commit

Permalink
[analyzer] [NFC] Move ObjKind into a separate top-level enum in Retai…
Browse files Browse the repository at this point in the history
…nSummaryManager.

Allows using it in future outside of RetEffect.

Differential Revision: https://reviews.llvm.org/D56039

llvm-svn: 350857
  • Loading branch information
George Karpenkov committed Jan 10, 2019
1 parent 52791c6 commit 7e3016d
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 69 deletions.
43 changes: 22 additions & 21 deletions clang/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h
Expand Up @@ -36,6 +36,22 @@ using namespace ento;
namespace clang {
namespace ento {

/// Determines the object kind of a tracked object.
enum class ObjKind {
/// Indicates that the tracked object is a CF object. This is
/// important between GC and non-GC code.
CF,
/// Indicates that the tracked object is an Objective-C object.
ObjC,
/// Indicates that the tracked object could be a CF or Objective-C object.
AnyObj,
/// Indicates that the tracked object is a generalized object.
Generalized,

/// A descendant of OSObject.
OS
};

/// An ArgEffect summarizes the retain count behavior on an argument or receiver
/// to a function or method.
enum ArgEffect {
Expand Down Expand Up @@ -144,27 +160,12 @@ class RetEffect {
NoRetHard
};

/// Determines the object kind of a tracked object.
enum ObjKind {
/// Indicates that the tracked object is a CF object. This is
/// important between GC and non-GC code.
CF,
/// Indicates that the tracked object is an Objective-C object.
ObjC,
/// Indicates that the tracked object could be a CF or Objective-C object.
AnyObj,
/// Indicates that the tracked object is a generalized object.
Generalized,

/// A descendant of OSObject.
OS
};

private:
Kind K;
ObjKind O;

RetEffect(Kind k, ObjKind o = AnyObj) : K(k), O(o) {}
RetEffect(Kind k, ObjKind o = ObjKind::AnyObj) : K(k), O(o) {}

public:
Kind getKind() const { return K; }
Expand All @@ -184,7 +185,7 @@ class RetEffect {
}

static RetEffect MakeOwnedWhenTrackedReceiver() {
return RetEffect(OwnedWhenTrackedReceiver, ObjC);
return RetEffect(OwnedWhenTrackedReceiver, ObjKind::ObjC);
}

static RetEffect MakeOwned(ObjKind o) {
Expand All @@ -194,7 +195,7 @@ class RetEffect {
return RetEffect(NotOwnedSymbol, o);
}
static RetEffect MakeGCNotOwned() {
return RetEffect(GCNotOwnedSymbol, ObjC);
return RetEffect(GCNotOwnedSymbol, ObjKind::ObjC);
}
static RetEffect MakeNoRet() {
return RetEffect(NoRet);
Expand Down Expand Up @@ -659,9 +660,9 @@ class RetainSummaryManager {
TrackObjCAndCFObjects(trackObjCAndCFObjects),
TrackOSObjects(trackOSObjects),
AF(BPAlloc),
ObjCAllocRetE(usesARC ? RetEffect::MakeNotOwned(RetEffect::ObjC)
: RetEffect::MakeOwned(RetEffect::ObjC)),
ObjCInitRetE(usesARC ? RetEffect::MakeNotOwned(RetEffect::ObjC)
ObjCAllocRetE(usesARC ? RetEffect::MakeNotOwned(ObjKind::ObjC)
: RetEffect::MakeOwned(ObjKind::ObjC)),
ObjCInitRetE(usesARC ? RetEffect::MakeNotOwned(ObjKind::ObjC)
: RetEffect::MakeOwnedWhenTrackedReceiver()) {
InitializeClassMethodSummaries();
InitializeMethodSummaries();
Expand Down
14 changes: 7 additions & 7 deletions clang/lib/ARCMigrate/ObjCMT.cpp
Expand Up @@ -1460,14 +1460,14 @@ void ObjCMigrateASTConsumer::AddCFAnnotations(ASTContext &Ctx,
if (!ResultAnnotated) {
RetEffect Ret = CE.getReturnValue();
const char *AnnotationString = nullptr;
if (Ret.getObjKind() == RetEffect::CF) {
if (Ret.getObjKind() == ObjKind::CF) {
if (Ret.isOwned() && NSAPIObj->isMacroDefined("CF_RETURNS_RETAINED"))
AnnotationString = " CF_RETURNS_RETAINED";
else if (Ret.notOwned() &&
NSAPIObj->isMacroDefined("CF_RETURNS_NOT_RETAINED"))
AnnotationString = " CF_RETURNS_NOT_RETAINED";
}
else if (Ret.getObjKind() == RetEffect::ObjC) {
else if (Ret.getObjKind() == ObjKind::ObjC) {
if (Ret.isOwned() && NSAPIObj->isMacroDefined("NS_RETURNS_RETAINED"))
AnnotationString = " NS_RETURNS_RETAINED";
}
Expand Down Expand Up @@ -1520,7 +1520,7 @@ ObjCMigrateASTConsumer::CF_BRIDGING_KIND
bool ReturnCFAudited = false;
if (!FuncIsReturnAnnotated) {
RetEffect Ret = CE.getReturnValue();
if (Ret.getObjKind() == RetEffect::CF &&
if (Ret.getObjKind() == ObjKind::CF &&
(Ret.isOwned() || Ret.notOwned()))
ReturnCFAudited = true;
else if (!AuditedType(FuncDecl->getReturnType()))
Expand Down Expand Up @@ -1574,14 +1574,14 @@ void ObjCMigrateASTConsumer::AddCFAnnotations(ASTContext &Ctx,
if (!ResultAnnotated) {
RetEffect Ret = CE.getReturnValue();
const char *AnnotationString = nullptr;
if (Ret.getObjKind() == RetEffect::CF) {
if (Ret.getObjKind() == ObjKind::CF) {
if (Ret.isOwned() && NSAPIObj->isMacroDefined("CF_RETURNS_RETAINED"))
AnnotationString = " CF_RETURNS_RETAINED";
else if (Ret.notOwned() &&
NSAPIObj->isMacroDefined("CF_RETURNS_NOT_RETAINED"))
AnnotationString = " CF_RETURNS_NOT_RETAINED";
}
else if (Ret.getObjKind() == RetEffect::ObjC) {
else if (Ret.getObjKind() == ObjKind::ObjC) {
ObjCMethodFamily OMF = MethodDecl->getMethodFamily();
switch (OMF) {
case clang::OMF_alloc:
Expand Down Expand Up @@ -1649,8 +1649,8 @@ void ObjCMigrateASTConsumer::migrateAddMethodAnnotation(

if (!MethodIsReturnAnnotated) {
RetEffect Ret = CE.getReturnValue();
if ((Ret.getObjKind() == RetEffect::CF ||
Ret.getObjKind() == RetEffect::ObjC) &&
if ((Ret.getObjKind() == ObjKind::CF ||
Ret.getObjKind() == ObjKind::ObjC) &&
(Ret.isOwned() || Ret.notOwned())) {
AddCFAnnotations(Ctx, CE, MethodDecl, false);
return;
Expand Down
Expand Up @@ -299,12 +299,12 @@ void RetainCountChecker::processObjCLiterals(CheckerContext &C,
}

// Return the object as autoreleased.
// RetEffect RE = RetEffect::MakeNotOwned(RetEffect::ObjC);
// RetEffect RE = RetEffect::MakeNotOwned(ObjKind::ObjC);
if (SymbolRef sym =
state->getSVal(Ex, pred->getLocationContext()).getAsSymbol()) {
QualType ResultTy = Ex->getType();
state = setRefBinding(state, sym,
RefVal::makeNotOwned(RetEffect::ObjC, ResultTy));
RefVal::makeNotOwned(ObjKind::ObjC, ResultTy));
}

C.addTransition(state);
Expand All @@ -330,7 +330,7 @@ void RetainCountChecker::checkPostStmt(const ObjCBoxedExpr *Ex,
if (SymbolRef Sym = Pred->getSVal(Ex).getAsSymbol()) {
QualType ResultTy = Ex->getType();
State = setRefBinding(State, Sym,
RefVal::makeNotOwned(RetEffect::ObjC, ResultTy));
RefVal::makeNotOwned(ObjKind::ObjC, ResultTy));
}

C.addTransition(State);
Expand All @@ -351,11 +351,11 @@ void RetainCountChecker::checkPostStmt(const ObjCIvarRefExpr *IRE,
// forgiving about what the surrounding code is allowed to do.

QualType Ty = Sym->getType();
RetEffect::ObjKind Kind;
ObjKind Kind;
if (Ty->isObjCRetainableType())
Kind = RetEffect::ObjC;
Kind = ObjKind::ObjC;
else if (coreFoundation::isCFObjectRef(Ty))
Kind = RetEffect::CF;
Kind = ObjKind::CF;
else
return;

Expand Down Expand Up @@ -514,7 +514,7 @@ static bool isPointerToObject(QualType QT) {
/// OSObjects are escaped when passed to void * / etc.
static bool shouldEscapeArgumentOnCall(const CallEvent &CE, unsigned ArgIdx,
const RefVal *TrackedValue) {
if (TrackedValue->getObjKind() != RetEffect::OS)
if (TrackedValue->getObjKind() != ObjKind::OS)
return false;
if (ArgIdx >= CE.parameters().size())
return false;
Expand Down Expand Up @@ -583,7 +583,7 @@ static ProgramStateRef updateOutParameter(ProgramStateRef State,
switch (Effect) {
case UnretainedOutParameter:
State = setRefBinding(State, Pointee,
RefVal::makeNotOwned(RetEffect::CF, PointeeTy));
RefVal::makeNotOwned(ObjKind::CF, PointeeTy));
break;
case RetainedOutParameter:
// Do nothing. Retained out parameters will either point to a +1 reference
Expand Down Expand Up @@ -1407,11 +1407,11 @@ void RetainCountChecker::checkBeginFunction(CheckerContext &Ctx) const {
const ArgEffect *AE = CalleeSideArgEffects.lookup(idx);
if (AE && *AE == DecRef && isISLObjectRef(Ty)) {
state = setRefBinding(
state, Sym, RefVal::makeOwned(RetEffect::ObjKind::Generalized, Ty));
state, Sym, RefVal::makeOwned(ObjKind::Generalized, Ty));
} else if (isISLObjectRef(Ty)) {
state = setRefBinding(
state, Sym,
RefVal::makeNotOwned(RetEffect::ObjKind::Generalized, Ty));
RefVal::makeNotOwned(ObjKind::Generalized, Ty));
}
}

Expand Down
Expand Up @@ -94,7 +94,7 @@ class RefVal {

/// The kind of object being tracked (CF or ObjC or OSObject), if known.
///
/// See the RetEffect::ObjKind enum for possible values.
/// See the ObjKind enum for possible values.
unsigned RawObjectKind : 3;

/// True if the current state and/or retain count may turn out to not be the
Expand All @@ -108,7 +108,7 @@ class RefVal {
/// them.
unsigned RawIvarAccessHistory : 2;

RefVal(Kind k, RetEffect::ObjKind o, unsigned cnt, unsigned acnt, QualType t,
RefVal(Kind k, ObjKind o, unsigned cnt, unsigned acnt, QualType t,
IvarAccessHistory IvarAccess)
: Cnt(cnt), ACnt(acnt), T(t), RawKind(static_cast<unsigned>(k)),
RawObjectKind(static_cast<unsigned>(o)),
Expand All @@ -121,8 +121,8 @@ class RefVal {
public:
Kind getKind() const { return static_cast<Kind>(RawKind); }

RetEffect::ObjKind getObjKind() const {
return static_cast<RetEffect::ObjKind>(RawObjectKind);
ObjKind getObjKind() const {
return static_cast<ObjKind>(RawObjectKind);
}

unsigned getCount() const { return Cnt; }
Expand Down Expand Up @@ -170,15 +170,15 @@ class RefVal {
/// current function, at least partially.
///
/// Most commonly, this is an owned object with a retain count of +1.
static RefVal makeOwned(RetEffect::ObjKind o, QualType t) {
static RefVal makeOwned(ObjKind o, QualType t) {
return RefVal(Owned, o, /*Count=*/1, 0, t, IvarAccessHistory::None);
}

/// Create a state for an object whose lifetime is not the responsibility of
/// the current function.
///
/// Most commonly, this is an unowned object with a retain count of +0.
static RefVal makeNotOwned(RetEffect::ObjKind o, QualType t) {
static RefVal makeNotOwned(ObjKind o, QualType t) {
return RefVal(NotOwned, o, /*Count=*/0, 0, t, IvarAccessHistory::None);
}

Expand Down
Expand Up @@ -156,17 +156,17 @@ static void generateDiagnosticsForCallLike(ProgramStateRef CurrSt,
}
}

if (CurrV.getObjKind() == RetEffect::CF) {
if (CurrV.getObjKind() == ObjKind::CF) {
os << " returns a Core Foundation object of type "
<< Sym->getType().getAsString() << " with a ";
} else if (CurrV.getObjKind() == RetEffect::OS) {
} else if (CurrV.getObjKind() == ObjKind::OS) {
os << " returns an OSObject of type " << getPrettyTypeName(Sym->getType())
<< " with a ";
} else if (CurrV.getObjKind() == RetEffect::Generalized) {
} else if (CurrV.getObjKind() == ObjKind::Generalized) {
os << " returns an object of type " << Sym->getType().getAsString()
<< " with a ";
} else {
assert(CurrV.getObjKind() == RetEffect::ObjC);
assert(CurrV.getObjKind() == ObjKind::ObjC);
QualType T = Sym->getType();
if (!isa<ObjCObjectPointerType>(T)) {
os << " returns an Objective-C object with a ";
Expand Down

0 comments on commit 7e3016d

Please sign in to comment.