diff options
author | Anna Zaks <ganna@apple.com> | 2012-08-07 05:12:24 +0000 |
---|---|---|
committer | Anna Zaks <ganna@apple.com> | 2012-08-07 05:12:24 +0000 |
commit | 8ed21ef726be89ef7151b5ff397631379bd8a537 (patch) | |
tree | 4794e502bf86b76054fd18cc9db5ff78e63f4eda | |
parent | 387611eaf8d8f000283bed0464597bc4e082dd7f (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.cpp | 3 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Core/CallEvent.cpp | 4 | ||||
-rw-r--r-- | test/Analysis/inlining/ObjCDynTypePopagation.m | 18 |
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; +} |