DynamicTypePropagation.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. //== DynamicTypePropagation.cpp -------------------------------- -*- C++ -*--=//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. //
  10. // This checker defines the rules for dynamic type gathering and propagation.
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #include "ClangSACheckers.h"
  14. #include "clang/Basic/Builtins.h"
  15. #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
  16. #include "clang/StaticAnalyzer/Core/Checker.h"
  17. #include "clang/StaticAnalyzer/Core/CheckerManager.h"
  18. #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
  19. #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
  20. #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
  21. using namespace clang;
  22. using namespace ento;
  23. namespace {
  24. class DynamicTypePropagation:
  25. public Checker< check::PreCall,
  26. check::PostCall,
  27. check::PostStmt<ImplicitCastExpr>,
  28. check::PostStmt<CXXNewExpr> > {
  29. const ObjCObjectType *getObjectTypeForAllocAndNew(const ObjCMessageExpr *MsgE,
  30. CheckerContext &C) const;
  31. /// \brief Return a better dynamic type if one can be derived from the cast.
  32. const ObjCObjectPointerType *getBetterObjCType(const Expr *CastE,
  33. CheckerContext &C) const;
  34. public:
  35. void checkPreCall(const CallEvent &Call, CheckerContext &C) const;
  36. void checkPostCall(const CallEvent &Call, CheckerContext &C) const;
  37. void checkPostStmt(const ImplicitCastExpr *CastE, CheckerContext &C) const;
  38. void checkPostStmt(const CXXNewExpr *NewE, CheckerContext &C) const;
  39. };
  40. }
  41. static void recordFixedType(const MemRegion *Region, const CXXMethodDecl *MD,
  42. CheckerContext &C) {
  43. assert(Region);
  44. assert(MD);
  45. ASTContext &Ctx = C.getASTContext();
  46. QualType Ty = Ctx.getPointerType(Ctx.getRecordType(MD->getParent()));
  47. ProgramStateRef State = C.getState();
  48. State = State->setDynamicTypeInfo(Region, Ty, /*CanBeSubclass=*/false);
  49. C.addTransition(State);
  50. return;
  51. }
  52. void DynamicTypePropagation::checkPreCall(const CallEvent &Call,
  53. CheckerContext &C) const {
  54. if (const CXXConstructorCall *Ctor = dyn_cast<CXXConstructorCall>(&Call)) {
  55. // C++11 [class.cdtor]p4: When a virtual function is called directly or
  56. // indirectly from a constructor or from a destructor, including during
  57. // the construction or destruction of the class's non-static data members,
  58. // and the object to which the call applies is the object under
  59. // construction or destruction, the function called is the final overrider
  60. // in the constructor's or destructor's class and not one overriding it in
  61. // a more-derived class.
  62. switch (Ctor->getOriginExpr()->getConstructionKind()) {
  63. case CXXConstructExpr::CK_Complete:
  64. case CXXConstructExpr::CK_Delegating:
  65. // No additional type info necessary.
  66. return;
  67. case CXXConstructExpr::CK_NonVirtualBase:
  68. case CXXConstructExpr::CK_VirtualBase:
  69. if (const MemRegion *Target = Ctor->getCXXThisVal().getAsRegion())
  70. recordFixedType(Target, Ctor->getDecl(), C);
  71. return;
  72. }
  73. return;
  74. }
  75. if (const CXXDestructorCall *Dtor = dyn_cast<CXXDestructorCall>(&Call)) {
  76. // C++11 [class.cdtor]p4 (see above)
  77. if (!Dtor->isBaseDestructor())
  78. return;
  79. const MemRegion *Target = Dtor->getCXXThisVal().getAsRegion();
  80. if (!Target)
  81. return;
  82. const Decl *D = Dtor->getDecl();
  83. if (!D)
  84. return;
  85. recordFixedType(Target, cast<CXXDestructorDecl>(D), C);
  86. return;
  87. }
  88. }
  89. void DynamicTypePropagation::checkPostCall(const CallEvent &Call,
  90. CheckerContext &C) const {
  91. // We can obtain perfect type info for return values from some calls.
  92. if (const ObjCMethodCall *Msg = dyn_cast<ObjCMethodCall>(&Call)) {
  93. // Get the returned value if it's a region.
  94. const MemRegion *RetReg = Call.getReturnValue().getAsRegion();
  95. if (!RetReg)
  96. return;
  97. ProgramStateRef State = C.getState();
  98. const ObjCMethodDecl *D = Msg->getDecl();
  99. if (D && D->hasRelatedResultType()) {
  100. switch (Msg->getMethodFamily()) {
  101. default:
  102. break;
  103. // We assume that the type of the object returned by alloc and new are the
  104. // pointer to the object of the class specified in the receiver of the
  105. // message.
  106. case OMF_alloc:
  107. case OMF_new: {
  108. // Get the type of object that will get created.
  109. const ObjCMessageExpr *MsgE = Msg->getOriginExpr();
  110. const ObjCObjectType *ObjTy = getObjectTypeForAllocAndNew(MsgE, C);
  111. if (!ObjTy)
  112. return;
  113. QualType DynResTy =
  114. C.getASTContext().getObjCObjectPointerType(QualType(ObjTy, 0));
  115. C.addTransition(State->setDynamicTypeInfo(RetReg, DynResTy, false));
  116. break;
  117. }
  118. case OMF_init: {
  119. // Assume, the result of the init method has the same dynamic type as
  120. // the receiver and propagate the dynamic type info.
  121. const MemRegion *RecReg = Msg->getReceiverSVal().getAsRegion();
  122. if (!RecReg)
  123. return;
  124. DynamicTypeInfo RecDynType = State->getDynamicTypeInfo(RecReg);
  125. C.addTransition(State->setDynamicTypeInfo(RetReg, RecDynType));
  126. break;
  127. }
  128. }
  129. }
  130. return;
  131. }
  132. if (const CXXConstructorCall *Ctor = dyn_cast<CXXConstructorCall>(&Call)) {
  133. // We may need to undo the effects of our pre-call check.
  134. switch (Ctor->getOriginExpr()->getConstructionKind()) {
  135. case CXXConstructExpr::CK_Complete:
  136. case CXXConstructExpr::CK_Delegating:
  137. // No additional work necessary.
  138. // Note: This will leave behind the actual type of the object for
  139. // complete constructors, but arguably that's a good thing, since it
  140. // means the dynamic type info will be correct even for objects
  141. // constructed with operator new.
  142. return;
  143. case CXXConstructExpr::CK_NonVirtualBase:
  144. case CXXConstructExpr::CK_VirtualBase:
  145. if (const MemRegion *Target = Ctor->getCXXThisVal().getAsRegion()) {
  146. // We just finished a base constructor. Now we can use the subclass's
  147. // type when resolving virtual calls.
  148. const Decl *D = C.getLocationContext()->getDecl();
  149. recordFixedType(Target, cast<CXXConstructorDecl>(D), C);
  150. }
  151. return;
  152. }
  153. }
  154. }
  155. void DynamicTypePropagation::checkPostStmt(const ImplicitCastExpr *CastE,
  156. CheckerContext &C) const {
  157. // We only track dynamic type info for regions.
  158. const MemRegion *ToR = C.getSVal(CastE).getAsRegion();
  159. if (!ToR)
  160. return;
  161. switch (CastE->getCastKind()) {
  162. default:
  163. break;
  164. case CK_BitCast:
  165. // Only handle ObjCObjects for now.
  166. if (const Type *NewTy = getBetterObjCType(CastE, C))
  167. C.addTransition(C.getState()->setDynamicTypeInfo(ToR, QualType(NewTy,0)));
  168. break;
  169. }
  170. return;
  171. }
  172. void DynamicTypePropagation::checkPostStmt(const CXXNewExpr *NewE,
  173. CheckerContext &C) const {
  174. if (NewE->isArray())
  175. return;
  176. // We only track dynamic type info for regions.
  177. const MemRegion *MR = C.getSVal(NewE).getAsRegion();
  178. if (!MR)
  179. return;
  180. C.addTransition(C.getState()->setDynamicTypeInfo(MR, NewE->getType(),
  181. /*CanBeSubclass=*/false));
  182. }
  183. const ObjCObjectType *
  184. DynamicTypePropagation::getObjectTypeForAllocAndNew(const ObjCMessageExpr *MsgE,
  185. CheckerContext &C) const {
  186. if (MsgE->getReceiverKind() == ObjCMessageExpr::Class) {
  187. if (const ObjCObjectType *ObjTy
  188. = MsgE->getClassReceiver()->getAs<ObjCObjectType>())
  189. return ObjTy;
  190. }
  191. if (MsgE->getReceiverKind() == ObjCMessageExpr::SuperClass) {
  192. if (const ObjCObjectType *ObjTy
  193. = MsgE->getSuperType()->getAs<ObjCObjectType>())
  194. return ObjTy;
  195. }
  196. const Expr *RecE = MsgE->getInstanceReceiver();
  197. if (!RecE)
  198. return nullptr;
  199. RecE= RecE->IgnoreParenImpCasts();
  200. if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(RecE)) {
  201. const StackFrameContext *SFCtx = C.getStackFrame();
  202. // Are we calling [self alloc]? If this is self, get the type of the
  203. // enclosing ObjC class.
  204. if (DRE->getDecl() == SFCtx->getSelfDecl()) {
  205. if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(SFCtx->getDecl()))
  206. if (const ObjCObjectType *ObjTy =
  207. dyn_cast<ObjCObjectType>(MD->getClassInterface()->getTypeForDecl()))
  208. return ObjTy;
  209. }
  210. }
  211. return nullptr;
  212. }
  213. // Return a better dynamic type if one can be derived from the cast.
  214. // Compare the current dynamic type of the region and the new type to which we
  215. // are casting. If the new type is lower in the inheritance hierarchy, pick it.
  216. const ObjCObjectPointerType *
  217. DynamicTypePropagation::getBetterObjCType(const Expr *CastE,
  218. CheckerContext &C) const {
  219. const MemRegion *ToR = C.getSVal(CastE).getAsRegion();
  220. assert(ToR);
  221. // Get the old and new types.
  222. const ObjCObjectPointerType *NewTy =
  223. CastE->getType()->getAs<ObjCObjectPointerType>();
  224. if (!NewTy)
  225. return nullptr;
  226. QualType OldDTy = C.getState()->getDynamicTypeInfo(ToR).getType();
  227. if (OldDTy.isNull()) {
  228. return NewTy;
  229. }
  230. const ObjCObjectPointerType *OldTy =
  231. OldDTy->getAs<ObjCObjectPointerType>();
  232. if (!OldTy)
  233. return nullptr;
  234. // Id the old type is 'id', the new one is more precise.
  235. if (OldTy->isObjCIdType() && !NewTy->isObjCIdType())
  236. return NewTy;
  237. // Return new if it's a subclass of old.
  238. const ObjCInterfaceDecl *ToI = NewTy->getInterfaceDecl();
  239. const ObjCInterfaceDecl *FromI = OldTy->getInterfaceDecl();
  240. if (ToI && FromI && FromI->isSuperClassOf(ToI))
  241. return NewTy;
  242. return nullptr;
  243. }
  244. void ento::registerDynamicTypePropagation(CheckerManager &mgr) {
  245. mgr.registerChecker<DynamicTypePropagation>();
  246. }