aboutsummaryrefslogtreecommitdiff
path: root/lib/Analysis
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Analysis')
-rw-r--r--lib/Analysis/BasicObjCFoundationChecks.cpp31
-rw-r--r--lib/Analysis/CFRefCount.cpp94
-rw-r--r--lib/Analysis/CheckNSError.cpp20
-rw-r--r--lib/Analysis/CheckObjCInstMethSignature.cpp4
4 files changed, 66 insertions, 83 deletions
diff --git a/lib/Analysis/BasicObjCFoundationChecks.cpp b/lib/Analysis/BasicObjCFoundationChecks.cpp
index aa85769157..b454a3605c 100644
--- a/lib/Analysis/BasicObjCFoundationChecks.cpp
+++ b/lib/Analysis/BasicObjCFoundationChecks.cpp
@@ -31,26 +31,21 @@
using namespace clang;
-static ObjCInterfaceType* GetReceiverType(ObjCMessageExpr* ME) {
- Expr* Receiver = ME->getReceiver();
+static const ObjCInterfaceType* GetReceiverType(const ObjCMessageExpr* ME) {
+ const Expr* Receiver = ME->getReceiver();
if (!Receiver)
return NULL;
- QualType X = Receiver->getType();
-
- if (X->isPointerType()) {
- Type* TP = X.getTypePtr();
- const PointerType* T = TP->getAsPointerType();
- return dyn_cast<ObjCInterfaceType>(T->getPointeeType().getTypePtr());
- }
+ if (const ObjCObjectPointerType *PT =
+ Receiver->getType()->getAsObjCObjectPointerType())
+ return PT->getInterfaceType();
- // FIXME: Support ObjCQualifiedIdType?
return NULL;
}
-static const char* GetReceiverNameType(ObjCMessageExpr* ME) {
- ObjCInterfaceType* ReceiverType = GetReceiverType(ME);
+static const char* GetReceiverNameType(const ObjCMessageExpr* ME) {
+ const ObjCInterfaceType *ReceiverType = GetReceiverType(ME);
return ReceiverType ? ReceiverType->getDecl()->getIdentifier()->getName()
: NULL;
}
@@ -67,7 +62,7 @@ class VISIBILITY_HIDDEN BasicObjCFoundationChecks : public GRSimpleAPICheck {
BugReporter& BR;
ASTContext &Ctx;
- bool isNSString(ObjCInterfaceType* T, const char* suffix);
+ bool isNSString(const ObjCInterfaceType *T, const char* suffix);
bool AuditNSString(NodeTy* N, ObjCMessageExpr* ME);
void Warn(NodeTy* N, Expr* E, const std::string& s);
@@ -114,7 +109,7 @@ bool BasicObjCFoundationChecks::Audit(ExplodedNode<GRState>* N,
ObjCMessageExpr* ME =
cast<ObjCMessageExpr>(cast<PostStmt>(N->getLocation()).getStmt());
- ObjCInterfaceType* ReceiverType = GetReceiverType(ME);
+ const ObjCInterfaceType *ReceiverType = GetReceiverType(ME);
if (!ReceiverType)
return false;
@@ -129,8 +124,7 @@ bool BasicObjCFoundationChecks::Audit(ExplodedNode<GRState>* N,
name += 2;
- // FIXME: Make all of this faster.
-
+ // FIXME: Make all of this faster.
if (isNSString(ReceiverType, name))
return AuditNSString(N, ME);
@@ -163,9 +157,8 @@ bool BasicObjCFoundationChecks::CheckNilArg(NodeTy* N, unsigned Arg) {
// NSString checking.
//===----------------------------------------------------------------------===//
-bool BasicObjCFoundationChecks::isNSString(ObjCInterfaceType* T,
- const char* suffix) {
-
+bool BasicObjCFoundationChecks::isNSString(const ObjCInterfaceType *T,
+ const char* suffix) {
return !strcmp("String", suffix) || !strcmp("MutableString", suffix);
}
diff --git a/lib/Analysis/CFRefCount.cpp b/lib/Analysis/CFRefCount.cpp
index c74668cf0f..1cfd783492 100644
--- a/lib/Analysis/CFRefCount.cpp
+++ b/lib/Analysis/CFRefCount.cpp
@@ -547,14 +547,12 @@ public:
return I == M.end() ? M.find(ObjCSummaryKey(S)) : I;
}
- ObjCInterfaceDecl* getReceiverDecl(Expr* E) {
-
- const PointerType* PT = E->getType()->getAsPointerType();
- if (!PT) return 0;
-
- ObjCInterfaceType* OI = dyn_cast<ObjCInterfaceType>(PT->getPointeeType());
-
- return OI ? OI->getDecl() : 0;
+ const ObjCInterfaceDecl* getReceiverDecl(Expr* E) {
+ if (const ObjCObjectPointerType* PT =
+ E->getType()->getAsObjCObjectPointerType())
+ return PT->getInterfaceDecl();
+
+ return NULL;
}
iterator end() { return M.end(); }
@@ -564,7 +562,7 @@ public:
Selector S = ME->getSelector();
if (Expr* Receiver = ME->getReceiver()) {
- ObjCInterfaceDecl* OD = getReceiverDecl(Receiver);
+ const ObjCInterfaceDecl* OD = getReceiverDecl(Receiver);
return OD ? M[ObjCSummaryKey(OD->getIdentifier(), S)] : M[S];
}
@@ -886,20 +884,20 @@ bool RetainSummaryManager::isTrackedObjCObjectType(QualType Ty) {
if (!Ctx.isObjCObjectPointerType(Ty))
return false;
- // We assume that id<..>, id, and "Class" all represent tracked objects.
- const PointerType *PT = Ty->getAsPointerType();
- if (PT == 0)
+ const ObjCObjectPointerType *PT = Ty->getAsObjCObjectPointerType();
+
+ // Can be true for objects with the 'NSObject' attribute.
+ if (!PT)
return true;
-
- const ObjCInterfaceType *OT = PT->getPointeeType()->getAsObjCInterfaceType();
-
+
// We assume that id<..>, id, and "Class" all represent tracked objects.
- if (!OT)
+ if (PT->isObjCIdType() || PT->isObjCQualifiedIdType() ||
+ PT->isObjCClassType())
return true;
-
+
// Does the interface subclass NSObject?
// FIXME: We can memoize here if this gets too expensive.
- ObjCInterfaceDecl* ID = OT->getDecl();
+ const ObjCInterfaceDecl *ID = PT->getInterfaceDecl();
// Assume that anything declared with a forward declaration and no
// @interface subclasses NSObject.
@@ -908,7 +906,6 @@ bool RetainSummaryManager::isTrackedObjCObjectType(QualType Ty) {
IdentifierInfo* NSObjectII = &Ctx.Idents.get("NSObject");
-
for ( ; ID ; ID = ID->getSuperClass())
if (ID->getIdentifier() == NSObjectII)
return true;
@@ -977,7 +974,7 @@ RetainSummary* RetainSummaryManager::getSummary(FunctionDecl* FD) {
case 17:
// Handle: id NSMakeCollectable(CFTypeRef)
if (!memcmp(FName, "NSMakeCollectable", 17)) {
- S = (RetTy == Ctx.getObjCIdType())
+ S = (RetTy->isObjCIdType())
? getUnarySummary(FT, cfmakecollectable)
: getPersistentStopSummary();
}
@@ -2726,34 +2723,26 @@ CFRefLeakReport::CFRefLeakReport(CFRefBug& D, const CFRefCount &tf,
/// While the the return type can be queried directly from RetEx, when
/// invoking class methods we augment to the return type to be that of
/// a pointer to the class (as opposed it just being id).
-static QualType GetReturnType(Expr* RetE, ASTContext& Ctx) {
-
+static QualType GetReturnType(const Expr* RetE, ASTContext& Ctx) {
QualType RetTy = RetE->getType();
-
- // FIXME: We aren't handling id<...>.
- const PointerType* PT = RetTy->getAsPointerType();
- if (!PT)
- return RetTy;
-
- // If RetEx is not a message expression just return its type.
- // If RetEx is a message expression, return its types if it is something
+ // If RetE is not a message expression just return its type.
+ // If RetE is a message expression, return its types if it is something
/// more specific than id.
+ if (const ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(RetE))
+ if (const ObjCObjectPointerType *PT = RetTy->getAsObjCObjectPointerType())
+ if (PT->isObjCQualifiedIdType() || PT->isObjCIdType() ||
+ PT->isObjCClassType()) {
+ // At this point we know the return type of the message expression is
+ // id, id<...>, or Class. If we have an ObjCInterfaceDecl, we know this
+ // is a call to a class method whose type we can resolve. In such
+ // cases, promote the return type to XXX* (where XXX is the class).
+ const ObjCInterfaceDecl *D = ME->getClassInfo().first;
+ return !D ? RetTy : Ctx.getPointerType(Ctx.getObjCInterfaceType(D));
+ }
- ObjCMessageExpr* ME = dyn_cast<ObjCMessageExpr>(RetE);
-
- if (!ME || !Ctx.isObjCIdStructType(PT->getPointeeType()))
- return RetTy;
-
- ObjCInterfaceDecl* D = ME->getClassInfo().first;
-
- // At this point we know the return type of the message expression is id.
- // If we have an ObjCInterceDecl, we know this is a call to a class method
- // whose type we can resolve. In such cases, promote the return type to
- // Class*.
- return !D ? RetTy : Ctx.getPointerType(Ctx.getObjCInterfaceType(D));
+ return RetTy;
}
-
void CFRefCount::EvalSummary(ExplodedNodeSet<GRState>& Dst,
GRExprEngine& Eng,
GRStmtNodeBuilder<GRState>& Builder,
@@ -3009,26 +2998,21 @@ void CFRefCount::EvalObjCMessageExpr(ExplodedNodeSet<GRState>& Dst,
SVal V = St->getSValAsScalarOrLoc(Receiver);
SymbolRef Sym = V.getAsLocSymbol();
+
if (Sym) {
if (const RefVal* T = St->get<RefBindings>(Sym)) {
- QualType Ty = T->getType();
-
- if (const PointerType* PT = Ty->getAsPointerType()) {
- QualType PointeeTy = PT->getPointeeType();
-
- if (ObjCInterfaceType* IT = dyn_cast<ObjCInterfaceType>(PointeeTy))
- ID = IT->getDecl();
- }
+ if (const ObjCObjectPointerType* PT =
+ T->getType()->getAsObjCObjectPointerType())
+ ID = PT->getInterfaceDecl();
}
}
// FIXME: this is a hack. This may or may not be the actual method
// that is called.
if (!ID) {
- if (const PointerType *PT = Receiver->getType()->getAsPointerType())
- if (const ObjCInterfaceType *p =
- PT->getPointeeType()->getAsObjCInterfaceType())
- ID = p->getDecl();
+ if (const ObjCObjectPointerType *PT =
+ Receiver->getType()->getAsObjCObjectPointerType())
+ ID = PT->getInterfaceDecl();
}
// FIXME: The receiver could be a reference to a class, meaning that
diff --git a/lib/Analysis/CheckNSError.cpp b/lib/Analysis/CheckNSError.cpp
index c91442b5e8..c1382d0377 100644
--- a/lib/Analysis/CheckNSError.cpp
+++ b/lib/Analysis/CheckNSError.cpp
@@ -162,16 +162,22 @@ NSErrorCheck::CheckSignature(FunctionDecl& F, QualType& ResultTy,
bool NSErrorCheck::CheckNSErrorArgument(QualType ArgTy) {
const PointerType* PPT = ArgTy->getAsPointerType();
- if (!PPT) return false;
+ if (!PPT)
+ return false;
+
+ const ObjCObjectPointerType* PT =
+ PPT->getPointeeType()->getAsObjCObjectPointerType();
+
+ if (!PT)
+ return false;
- const PointerType* PT = PPT->getPointeeType()->getAsPointerType();
- if (!PT) return false;
+ const ObjCInterfaceDecl *ID = PT->getInterfaceDecl();
- const ObjCInterfaceType *IT =
- PT->getPointeeType()->getAsObjCInterfaceType();
+ // FIXME: Can ID ever be NULL?
+ if (ID)
+ return II == ID->getIdentifier();
- if (!IT) return false;
- return IT->getDecl()->getIdentifier() == II;
+ return false;
}
bool NSErrorCheck::CheckCFErrorArgument(QualType ArgTy) {
diff --git a/lib/Analysis/CheckObjCInstMethSignature.cpp b/lib/Analysis/CheckObjCInstMethSignature.cpp
index 28814867bd..c4e586d2e4 100644
--- a/lib/Analysis/CheckObjCInstMethSignature.cpp
+++ b/lib/Analysis/CheckObjCInstMethSignature.cpp
@@ -30,8 +30,8 @@ static bool AreTypesCompatible(QualType Derived, QualType Ancestor,
// Right now don't compare the compatibility of pointers. That involves
// looking at subtyping relationships. FIXME: Future patch.
- if ((Derived->isPointerType() || Derived->isObjCQualifiedIdType()) &&
- (Ancestor->isPointerType() || Ancestor->isObjCQualifiedIdType()))
+ if ((Derived->isPointerType() || Derived->isObjCObjectPointerType()) &&
+ (Ancestor->isPointerType() || Ancestor->isObjCObjectPointerType()))
return true;
return C.typesAreCompatible(Derived, Ancestor);