diff options
| author | Anna Zaks <ganna@apple.com> | 2013-02-25 22:10:34 +0000 |
|---|---|---|
| committer | Anna Zaks <ganna@apple.com> | 2013-02-25 22:10:34 +0000 |
| commit | ba342723214c76389ad7313728a1a330b9fc927e (patch) | |
| tree | 266ecf3220535771273d3d070fdfce1ab59fa0d9 /clang/lib/StaticAnalyzer/Checkers | |
| parent | 0adc042392028828f6106cf2c1494db8ecfb7ced (diff) | |
| download | bcm5719-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.cpp | 62 |
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; } |

