aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnna Zaks <ganna@apple.com>2012-08-07 05:12:24 +0000
committerAnna Zaks <ganna@apple.com>2012-08-07 05:12:24 +0000
commit8ed21ef726be89ef7151b5ff397631379bd8a537 (patch)
tree4794e502bf86b76054fd18cc9db5ff78e63f4eda
parent387611eaf8d8f000283bed0464597bc4e082dd7f (diff)
[analyzer] Address Jordan's review of DynamicTypePropagation.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@161391 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp3
-rw-r--r--lib/StaticAnalyzer/Core/CallEvent.cpp4
-rw-r--r--test/Analysis/inlining/ObjCDynTypePopagation.m18
3 files changed, 20 insertions, 5 deletions
diff --git a/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp b/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp
index fec6c43dbd..d9edab8ede 100644
--- a/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp
+++ b/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp
@@ -75,7 +75,8 @@ void DynamicTypePropagation::checkPostCall(const CallEvent &Call,
// Assume, the result of the init method has the same dynamic type as
// the receiver and propagate the dynamic type info.
const MemRegion *RecReg = Msg->getReceiverSVal().getAsRegion();
- assert(RecReg);
+ if (!RecReg)
+ return;
DynamicTypeInfo RecDynType = State->getDynamicTypeInfo(RecReg);
C.addTransition(State->addDynamicTypeInfo(RetReg, RecDynType));
break;
diff --git a/lib/StaticAnalyzer/Core/CallEvent.cpp b/lib/StaticAnalyzer/Core/CallEvent.cpp
index 396e0f6d8d..006ca1043a 100644
--- a/lib/StaticAnalyzer/Core/CallEvent.cpp
+++ b/lib/StaticAnalyzer/Core/CallEvent.cpp
@@ -670,14 +670,14 @@ const Decl *ObjCMethodCall::getRuntimeDefinition() const {
const ObjCObjectPointerType *ReceiverT = 0;
QualType SupersType = E->getSuperType();
if (!SupersType.isNull()) {
- ReceiverT = cast<ObjCObjectPointerType>(SupersType.getTypePtr());
+ ReceiverT = cast<ObjCObjectPointerType>(SupersType);
} else {
const MemRegion *Receiver = getReceiverSVal().getAsRegion();
if (!Receiver)
return 0;
QualType DynType = getState()->getDynamicTypeInfo(Receiver).getType();
- ReceiverT = dyn_cast<ObjCObjectPointerType>(DynType.getTypePtr());
+ ReceiverT = dyn_cast<ObjCObjectPointerType>(DynType);
}
// Lookup the method implementation.
diff --git a/test/Analysis/inlining/ObjCDynTypePopagation.m b/test/Analysis/inlining/ObjCDynTypePopagation.m
index 425903242d..960449758b 100644
--- a/test/Analysis/inlining/ObjCDynTypePopagation.m
+++ b/test/Analysis/inlining/ObjCDynTypePopagation.m
@@ -1,6 +1,10 @@
// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-ipa=dynamic -verify %s
typedef signed char BOOL;
+typedef struct objc_class *Class;
+typedef struct objc_object {
+ Class isa;
+} *id;
void clang_analyzer_eval(BOOL);
@@ -84,10 +88,20 @@ MyClass *getObj();
clang_analyzer_eval([p getZero] == 0); // expected-warning{{TRUE}}
}
-// Test implisit cast.
+// Test implicit cast.
+// Note, in this case, p could also be a subclass of MyParent.
+ (void) testCastFromId:(id) a {
MyParent *p = a;
clang_analyzer_eval([p getZero] == 0); // expected-warning{{TRUE}}
}
+@end
-@end \ No newline at end of file
+// TODO: Would be nice to handle the case of dynamically obtained class info
+// as well. We need a MemRegion for class types for this.
+int testDynamicClass(BOOL coin) {
+ Class AllocClass = (coin ? [NSObject class] : [MyClass class]);
+ id x = [[AllocClass alloc] init];
+ if (coin)
+ return [x getZero];
+ return 1;
+}