TransUnbridgedCasts.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469
  1. //===--- TransUnbridgedCasts.cpp - Transformations to ARC mode ------------===//
  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. // rewriteUnbridgedCasts:
  11. //
  12. // A cast of non-objc pointer to an objc one is checked. If the non-objc pointer
  13. // is from a file-level variable, __bridge cast is used to convert it.
  14. // For the result of a function call that we know is +1/+0,
  15. // __bridge/CFBridgingRelease is used.
  16. //
  17. // NSString *str = (NSString *)kUTTypePlainText;
  18. // str = b ? kUTTypeRTF : kUTTypePlainText;
  19. // NSString *_uuidString = (NSString *)CFUUIDCreateString(kCFAllocatorDefault,
  20. // _uuid);
  21. // ---->
  22. // NSString *str = (__bridge NSString *)kUTTypePlainText;
  23. // str = (__bridge NSString *)(b ? kUTTypeRTF : kUTTypePlainText);
  24. // NSString *_uuidString = (NSString *)
  25. // CFBridgingRelease(CFUUIDCreateString(kCFAllocatorDefault, _uuid));
  26. //
  27. // For a C pointer to ObjC, for casting 'self', __bridge is used.
  28. //
  29. // CFStringRef str = (CFStringRef)self;
  30. // ---->
  31. // CFStringRef str = (__bridge CFStringRef)self;
  32. //
  33. // Uses of Block_copy/Block_release macros are rewritten:
  34. //
  35. // c = Block_copy(b);
  36. // Block_release(c);
  37. // ---->
  38. // c = [b copy];
  39. // <removed>
  40. //
  41. //===----------------------------------------------------------------------===//
  42. #include "Transforms.h"
  43. #include "Internals.h"
  44. #include "clang/AST/ASTContext.h"
  45. #include "clang/AST/Attr.h"
  46. #include "clang/AST/ParentMap.h"
  47. #include "clang/Analysis/DomainSpecific/CocoaConventions.h"
  48. #include "clang/Basic/SourceManager.h"
  49. #include "clang/Lex/Lexer.h"
  50. #include "clang/Sema/SemaDiagnostic.h"
  51. #include "llvm/ADT/SmallString.h"
  52. using namespace clang;
  53. using namespace arcmt;
  54. using namespace trans;
  55. namespace {
  56. class UnbridgedCastRewriter : public RecursiveASTVisitor<UnbridgedCastRewriter>{
  57. MigrationPass &Pass;
  58. IdentifierInfo *SelfII;
  59. std::unique_ptr<ParentMap> StmtMap;
  60. Decl *ParentD;
  61. Stmt *Body;
  62. mutable std::unique_ptr<ExprSet> Removables;
  63. public:
  64. UnbridgedCastRewriter(MigrationPass &pass)
  65. : Pass(pass), ParentD(nullptr), Body(nullptr) {
  66. SelfII = &Pass.Ctx.Idents.get("self");
  67. }
  68. void transformBody(Stmt *body, Decl *ParentD) {
  69. this->ParentD = ParentD;
  70. Body = body;
  71. StmtMap.reset(new ParentMap(body));
  72. TraverseStmt(body);
  73. }
  74. bool TraverseBlockDecl(BlockDecl *D) {
  75. // ParentMap does not enter into a BlockDecl to record its stmts, so use a
  76. // new UnbridgedCastRewriter to handle the block.
  77. UnbridgedCastRewriter(Pass).transformBody(D->getBody(), D);
  78. return true;
  79. }
  80. bool VisitCastExpr(CastExpr *E) {
  81. if (E->getCastKind() != CK_CPointerToObjCPointerCast &&
  82. E->getCastKind() != CK_BitCast &&
  83. E->getCastKind() != CK_AnyPointerToBlockPointerCast)
  84. return true;
  85. QualType castType = E->getType();
  86. Expr *castExpr = E->getSubExpr();
  87. QualType castExprType = castExpr->getType();
  88. if (castType->isObjCRetainableType() == castExprType->isObjCRetainableType())
  89. return true;
  90. bool exprRetainable = castExprType->isObjCIndirectLifetimeType();
  91. bool castRetainable = castType->isObjCIndirectLifetimeType();
  92. if (exprRetainable == castRetainable) return true;
  93. if (castExpr->isNullPointerConstant(Pass.Ctx,
  94. Expr::NPC_ValueDependentIsNull))
  95. return true;
  96. SourceLocation loc = castExpr->getExprLoc();
  97. if (loc.isValid() && Pass.Ctx.getSourceManager().isInSystemHeader(loc))
  98. return true;
  99. if (castType->isObjCRetainableType())
  100. transformNonObjCToObjCCast(E);
  101. else
  102. transformObjCToNonObjCCast(E);
  103. return true;
  104. }
  105. private:
  106. void transformNonObjCToObjCCast(CastExpr *E) {
  107. if (!E) return;
  108. // Global vars are assumed that are cast as unretained.
  109. if (isGlobalVar(E))
  110. if (E->getSubExpr()->getType()->isPointerType()) {
  111. castToObjCObject(E, /*retained=*/false);
  112. return;
  113. }
  114. // If the cast is directly over the result of a Core Foundation function
  115. // try to figure out whether it should be cast as retained or unretained.
  116. Expr *inner = E->IgnoreParenCasts();
  117. if (CallExpr *callE = dyn_cast<CallExpr>(inner)) {
  118. if (FunctionDecl *FD = callE->getDirectCallee()) {
  119. if (FD->hasAttr<CFReturnsRetainedAttr>()) {
  120. castToObjCObject(E, /*retained=*/true);
  121. return;
  122. }
  123. if (FD->hasAttr<CFReturnsNotRetainedAttr>()) {
  124. castToObjCObject(E, /*retained=*/false);
  125. return;
  126. }
  127. if (FD->isGlobal() &&
  128. FD->getIdentifier() &&
  129. ento::cocoa::isRefType(E->getSubExpr()->getType(), "CF",
  130. FD->getIdentifier()->getName())) {
  131. StringRef fname = FD->getIdentifier()->getName();
  132. if (fname.endswith("Retain") ||
  133. fname.find("Create") != StringRef::npos ||
  134. fname.find("Copy") != StringRef::npos) {
  135. // Do not migrate to couple of bridge transfer casts which
  136. // cancel each other out. Leave it unchanged so error gets user
  137. // attention instead.
  138. if (FD->getName() == "CFRetain" &&
  139. FD->getNumParams() == 1 &&
  140. FD->getParent()->isTranslationUnit() &&
  141. FD->isExternallyVisible()) {
  142. Expr *Arg = callE->getArg(0);
  143. if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Arg)) {
  144. const Expr *sub = ICE->getSubExpr();
  145. QualType T = sub->getType();
  146. if (T->isObjCObjectPointerType())
  147. return;
  148. }
  149. }
  150. castToObjCObject(E, /*retained=*/true);
  151. return;
  152. }
  153. if (fname.find("Get") != StringRef::npos) {
  154. castToObjCObject(E, /*retained=*/false);
  155. return;
  156. }
  157. }
  158. }
  159. }
  160. // If returning an ivar or a member of an ivar from a +0 method, use
  161. // a __bridge cast.
  162. Expr *base = inner->IgnoreParenImpCasts();
  163. while (isa<MemberExpr>(base))
  164. base = cast<MemberExpr>(base)->getBase()->IgnoreParenImpCasts();
  165. if (isa<ObjCIvarRefExpr>(base) &&
  166. isa<ReturnStmt>(StmtMap->getParentIgnoreParenCasts(E))) {
  167. if (ObjCMethodDecl *method = dyn_cast_or_null<ObjCMethodDecl>(ParentD)) {
  168. if (!method->hasAttr<NSReturnsRetainedAttr>()) {
  169. castToObjCObject(E, /*retained=*/false);
  170. return;
  171. }
  172. }
  173. }
  174. }
  175. void castToObjCObject(CastExpr *E, bool retained) {
  176. rewriteToBridgedCast(E, retained ? OBC_BridgeTransfer : OBC_Bridge);
  177. }
  178. void rewriteToBridgedCast(CastExpr *E, ObjCBridgeCastKind Kind) {
  179. Transaction Trans(Pass.TA);
  180. rewriteToBridgedCast(E, Kind, Trans);
  181. }
  182. void rewriteToBridgedCast(CastExpr *E, ObjCBridgeCastKind Kind,
  183. Transaction &Trans) {
  184. TransformActions &TA = Pass.TA;
  185. // We will remove the compiler diagnostic.
  186. if (!TA.hasDiagnostic(diag::err_arc_mismatched_cast,
  187. diag::err_arc_cast_requires_bridge,
  188. E->getLocStart())) {
  189. Trans.abort();
  190. return;
  191. }
  192. StringRef bridge;
  193. switch(Kind) {
  194. case OBC_Bridge:
  195. bridge = "__bridge "; break;
  196. case OBC_BridgeTransfer:
  197. bridge = "__bridge_transfer "; break;
  198. case OBC_BridgeRetained:
  199. bridge = "__bridge_retained "; break;
  200. }
  201. TA.clearDiagnostic(diag::err_arc_mismatched_cast,
  202. diag::err_arc_cast_requires_bridge,
  203. E->getLocStart());
  204. if (Kind == OBC_Bridge || !Pass.CFBridgingFunctionsDefined()) {
  205. if (CStyleCastExpr *CCE = dyn_cast<CStyleCastExpr>(E)) {
  206. TA.insertAfterToken(CCE->getLParenLoc(), bridge);
  207. } else {
  208. SourceLocation insertLoc = E->getSubExpr()->getLocStart();
  209. SmallString<128> newCast;
  210. newCast += '(';
  211. newCast += bridge;
  212. newCast += E->getType().getAsString(Pass.Ctx.getPrintingPolicy());
  213. newCast += ')';
  214. if (isa<ParenExpr>(E->getSubExpr())) {
  215. TA.insert(insertLoc, newCast.str());
  216. } else {
  217. newCast += '(';
  218. TA.insert(insertLoc, newCast.str());
  219. TA.insertAfterToken(E->getLocEnd(), ")");
  220. }
  221. }
  222. } else {
  223. assert(Kind == OBC_BridgeTransfer || Kind == OBC_BridgeRetained);
  224. SmallString<32> BridgeCall;
  225. Expr *WrapE = E->getSubExpr();
  226. SourceLocation InsertLoc = WrapE->getLocStart();
  227. SourceManager &SM = Pass.Ctx.getSourceManager();
  228. char PrevChar = *SM.getCharacterData(InsertLoc.getLocWithOffset(-1));
  229. if (Lexer::isIdentifierBodyChar(PrevChar, Pass.Ctx.getLangOpts()))
  230. BridgeCall += ' ';
  231. if (Kind == OBC_BridgeTransfer)
  232. BridgeCall += "CFBridgingRelease";
  233. else
  234. BridgeCall += "CFBridgingRetain";
  235. if (isa<ParenExpr>(WrapE)) {
  236. TA.insert(InsertLoc, BridgeCall);
  237. } else {
  238. BridgeCall += '(';
  239. TA.insert(InsertLoc, BridgeCall);
  240. TA.insertAfterToken(WrapE->getLocEnd(), ")");
  241. }
  242. }
  243. }
  244. void rewriteCastForCFRetain(CastExpr *castE, CallExpr *callE) {
  245. Transaction Trans(Pass.TA);
  246. Pass.TA.replace(callE->getSourceRange(), callE->getArg(0)->getSourceRange());
  247. rewriteToBridgedCast(castE, OBC_BridgeRetained, Trans);
  248. }
  249. void getBlockMacroRanges(CastExpr *E, SourceRange &Outer, SourceRange &Inner) {
  250. SourceManager &SM = Pass.Ctx.getSourceManager();
  251. SourceLocation Loc = E->getExprLoc();
  252. assert(Loc.isMacroID());
  253. SourceLocation MacroBegin, MacroEnd;
  254. std::tie(MacroBegin, MacroEnd) = SM.getImmediateExpansionRange(Loc);
  255. SourceRange SubRange = E->getSubExpr()->IgnoreParenImpCasts()->getSourceRange();
  256. SourceLocation InnerBegin = SM.getImmediateMacroCallerLoc(SubRange.getBegin());
  257. SourceLocation InnerEnd = SM.getImmediateMacroCallerLoc(SubRange.getEnd());
  258. Outer = SourceRange(MacroBegin, MacroEnd);
  259. Inner = SourceRange(InnerBegin, InnerEnd);
  260. }
  261. void rewriteBlockCopyMacro(CastExpr *E) {
  262. SourceRange OuterRange, InnerRange;
  263. getBlockMacroRanges(E, OuterRange, InnerRange);
  264. Transaction Trans(Pass.TA);
  265. Pass.TA.replace(OuterRange, InnerRange);
  266. Pass.TA.insert(InnerRange.getBegin(), "[");
  267. Pass.TA.insertAfterToken(InnerRange.getEnd(), " copy]");
  268. Pass.TA.clearDiagnostic(diag::err_arc_mismatched_cast,
  269. diag::err_arc_cast_requires_bridge,
  270. OuterRange);
  271. }
  272. void removeBlockReleaseMacro(CastExpr *E) {
  273. SourceRange OuterRange, InnerRange;
  274. getBlockMacroRanges(E, OuterRange, InnerRange);
  275. Transaction Trans(Pass.TA);
  276. Pass.TA.clearDiagnostic(diag::err_arc_mismatched_cast,
  277. diag::err_arc_cast_requires_bridge,
  278. OuterRange);
  279. if (!hasSideEffects(E, Pass.Ctx)) {
  280. if (tryRemoving(cast<Expr>(StmtMap->getParentIgnoreParenCasts(E))))
  281. return;
  282. }
  283. Pass.TA.replace(OuterRange, InnerRange);
  284. }
  285. bool tryRemoving(Expr *E) const {
  286. if (!Removables) {
  287. Removables.reset(new ExprSet);
  288. collectRemovables(Body, *Removables);
  289. }
  290. if (Removables->count(E)) {
  291. Pass.TA.removeStmt(E);
  292. return true;
  293. }
  294. return false;
  295. }
  296. void transformObjCToNonObjCCast(CastExpr *E) {
  297. SourceLocation CastLoc = E->getExprLoc();
  298. if (CastLoc.isMacroID()) {
  299. StringRef MacroName = Lexer::getImmediateMacroName(CastLoc,
  300. Pass.Ctx.getSourceManager(),
  301. Pass.Ctx.getLangOpts());
  302. if (MacroName == "Block_copy") {
  303. rewriteBlockCopyMacro(E);
  304. return;
  305. }
  306. if (MacroName == "Block_release") {
  307. removeBlockReleaseMacro(E);
  308. return;
  309. }
  310. }
  311. if (isSelf(E->getSubExpr()))
  312. return rewriteToBridgedCast(E, OBC_Bridge);
  313. CallExpr *callE;
  314. if (isPassedToCFRetain(E, callE))
  315. return rewriteCastForCFRetain(E, callE);
  316. ObjCMethodFamily family = getFamilyOfMessage(E->getSubExpr());
  317. if (family == OMF_retain)
  318. return rewriteToBridgedCast(E, OBC_BridgeRetained);
  319. if (family == OMF_autorelease || family == OMF_release) {
  320. std::string err = "it is not safe to cast to '";
  321. err += E->getType().getAsString(Pass.Ctx.getPrintingPolicy());
  322. err += "' the result of '";
  323. err += family == OMF_autorelease ? "autorelease" : "release";
  324. err += "' message; a __bridge cast may result in a pointer to a "
  325. "destroyed object and a __bridge_retained may leak the object";
  326. Pass.TA.reportError(err, E->getLocStart(),
  327. E->getSubExpr()->getSourceRange());
  328. Stmt *parent = E;
  329. do {
  330. parent = StmtMap->getParentIgnoreParenImpCasts(parent);
  331. } while (parent && isa<ExprWithCleanups>(parent));
  332. if (ReturnStmt *retS = dyn_cast_or_null<ReturnStmt>(parent)) {
  333. std::string note = "remove the cast and change return type of function "
  334. "to '";
  335. note += E->getSubExpr()->getType().getAsString(Pass.Ctx.getPrintingPolicy());
  336. note += "' to have the object automatically autoreleased";
  337. Pass.TA.reportNote(note, retS->getLocStart());
  338. }
  339. }
  340. Expr *subExpr = E->getSubExpr();
  341. // Look through pseudo-object expressions.
  342. if (PseudoObjectExpr *pseudo = dyn_cast<PseudoObjectExpr>(subExpr)) {
  343. subExpr = pseudo->getResultExpr();
  344. assert(subExpr && "no result for pseudo-object of non-void type?");
  345. }
  346. if (ImplicitCastExpr *implCE = dyn_cast<ImplicitCastExpr>(subExpr)) {
  347. if (implCE->getCastKind() == CK_ARCConsumeObject)
  348. return rewriteToBridgedCast(E, OBC_BridgeRetained);
  349. if (implCE->getCastKind() == CK_ARCReclaimReturnedObject)
  350. return rewriteToBridgedCast(E, OBC_Bridge);
  351. }
  352. bool isConsumed = false;
  353. if (isPassedToCParamWithKnownOwnership(E, isConsumed))
  354. return rewriteToBridgedCast(E, isConsumed ? OBC_BridgeRetained
  355. : OBC_Bridge);
  356. }
  357. static ObjCMethodFamily getFamilyOfMessage(Expr *E) {
  358. E = E->IgnoreParenCasts();
  359. if (ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(E))
  360. return ME->getMethodFamily();
  361. return OMF_None;
  362. }
  363. bool isPassedToCFRetain(Expr *E, CallExpr *&callE) const {
  364. if ((callE = dyn_cast_or_null<CallExpr>(
  365. StmtMap->getParentIgnoreParenImpCasts(E))))
  366. if (FunctionDecl *
  367. FD = dyn_cast_or_null<FunctionDecl>(callE->getCalleeDecl()))
  368. if (FD->getName() == "CFRetain" && FD->getNumParams() == 1 &&
  369. FD->getParent()->isTranslationUnit() &&
  370. FD->isExternallyVisible())
  371. return true;
  372. return false;
  373. }
  374. bool isPassedToCParamWithKnownOwnership(Expr *E, bool &isConsumed) const {
  375. if (CallExpr *callE = dyn_cast_or_null<CallExpr>(
  376. StmtMap->getParentIgnoreParenImpCasts(E)))
  377. if (FunctionDecl *
  378. FD = dyn_cast_or_null<FunctionDecl>(callE->getCalleeDecl())) {
  379. unsigned i = 0;
  380. for (unsigned e = callE->getNumArgs(); i != e; ++i) {
  381. Expr *arg = callE->getArg(i);
  382. if (arg == E || arg->IgnoreParenImpCasts() == E)
  383. break;
  384. }
  385. if (i < callE->getNumArgs() && i < FD->getNumParams()) {
  386. ParmVarDecl *PD = FD->getParamDecl(i);
  387. if (PD->hasAttr<CFConsumedAttr>()) {
  388. isConsumed = true;
  389. return true;
  390. }
  391. }
  392. }
  393. return false;
  394. }
  395. bool isSelf(Expr *E) const {
  396. E = E->IgnoreParenLValueCasts();
  397. if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
  398. if (ImplicitParamDecl *IPD = dyn_cast<ImplicitParamDecl>(DRE->getDecl()))
  399. if (IPD->getIdentifier() == SelfII)
  400. return true;
  401. return false;
  402. }
  403. };
  404. } // end anonymous namespace
  405. void trans::rewriteUnbridgedCasts(MigrationPass &pass) {
  406. BodyTransform<UnbridgedCastRewriter> trans(pass);
  407. trans.TraverseDecl(pass.Ctx.getTranslationUnitDecl());
  408. }