summaryrefslogtreecommitdiffstats
path: root/clang/lib/StaticAnalyzer/Checkers
diff options
context:
space:
mode:
authorAnna Zaks <ganna@apple.com>2013-02-25 22:10:34 +0000
committerAnna Zaks <ganna@apple.com>2013-02-25 22:10:34 +0000
commitba342723214c76389ad7313728a1a330b9fc927e (patch)
tree266ecf3220535771273d3d070fdfce1ab59fa0d9 /clang/lib/StaticAnalyzer/Checkers
parent0adc042392028828f6106cf2c1494db8ecfb7ced (diff)
downloadbcm5719-llvm-ba342723214c76389ad7313728a1a330b9fc927e.tar.gz
bcm5719-llvm-ba342723214c76389ad7313728a1a330b9fc927e.zip
[analyzer] Restrict ObjC type inference to methods that have related result type.
This addresses a case when we inline a wrong method due to incorrect dynamic type inference. Specifically, when user code contains a method from init family, which creates an instance of another class. Use hasRelatedResultType() to find out if our inference rules should be triggered. llvm-svn: 176054
Diffstat (limited to 'clang/lib/StaticAnalyzer/Checkers')
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp62
1 files changed, 32 insertions, 30 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp b/clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp
index 08af45df370..9f176a4b5bf 100644
--- a/clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp
@@ -110,38 +110,40 @@ void DynamicTypePropagation::checkPostCall(const CallEvent &Call,
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;
}
OpenPOWER on IntegriCloud