TransUnbridgedCasts.cpp 16 KB

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