return;
ProgramStateRef State = C.getState();
-
- switch (Msg->getMethodFamily()) {
- default:
- break;
-
- // We assume that the type of the object returned by alloc and new are the
- // pointer to the object of the class specified in the receiver of the
- // message.
- case OMF_alloc:
- case OMF_new: {
- // Get the type of object that will get created.
- const ObjCMessageExpr *MsgE = Msg->getOriginExpr();
- const ObjCObjectType *ObjTy = getObjectTypeForAllocAndNew(MsgE, C);
- if (!ObjTy)
- return;
- QualType DynResTy =
+ const ObjCMethodDecl *D = Msg->getDecl();
+
+ if (D && D->hasRelatedResultType()) {
+ switch (Msg->getMethodFamily()) {
+ default:
+ break;
+
+ // We assume that the type of the object returned by alloc and new are the
+ // pointer to the object of the class specified in the receiver of the
+ // message.
+ case OMF_alloc:
+ case OMF_new: {
+ // Get the type of object that will get created.
+ const ObjCMessageExpr *MsgE = Msg->getOriginExpr();
+ const ObjCObjectType *ObjTy = getObjectTypeForAllocAndNew(MsgE, C);
+ if (!ObjTy)
+ return;
+ QualType DynResTy =
C.getASTContext().getObjCObjectPointerType(QualType(ObjTy, 0));
- C.addTransition(State->setDynamicTypeInfo(RetReg, DynResTy, false));
- break;
- }
- case OMF_init: {
- // 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();
- if (!RecReg)
- return;
- DynamicTypeInfo RecDynType = State->getDynamicTypeInfo(RecReg);
- C.addTransition(State->setDynamicTypeInfo(RetReg, RecDynType));
- break;
- }
+ C.addTransition(State->setDynamicTypeInfo(RetReg, DynResTy, false));
+ break;
+ }
+ case OMF_init: {
+ // 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();
+ if (!RecReg)
+ return;
+ DynamicTypeInfo RecDynType = State->getDynamicTypeInfo(RecReg);
+ C.addTransition(State->setDynamicTypeInfo(RetReg, RecDynType));
+ break;
+ }
+ }
}
-
return;
}
return [x getZero];
return 1;
}
+
+@interface UserClass : NSObject
+- (PublicSubClass2 *) _newPublicSubClass2;
+- (int) getZero;
+- (void) callNew;
+@end
+
+@implementation UserClass
+- (PublicSubClass2 *) _newPublicSubClass2 {
+ return [[PublicSubClass2 alloc] init];
+}
+- (int) getZero { return 5; }
+- (void) callNew {
+ PublicSubClass2 *x = [self _newPublicSubClass2];
+ clang_analyzer_eval([x getZero] == 0); //expected-warning{{TRUE}}
+}
+@end
\ No newline at end of file