forked from OSchip/llvm-project
				
			[arcmt] In GC, error for use of CFMakeCollectable because it will leak the
object that it receives in ARC. llvm-svn: 143700
This commit is contained in:
		
							parent
							
								
									3eaa22af57
								
							
						
					
					
						commit
						d8cdfbc905
					
				| 
						 | 
					@ -22,27 +22,37 @@ class GCCollectableCallsChecker :
 | 
				
			||||||
  MigrationContext &MigrateCtx;
 | 
					  MigrationContext &MigrateCtx;
 | 
				
			||||||
  ParentMap &PMap;
 | 
					  ParentMap &PMap;
 | 
				
			||||||
  IdentifierInfo *NSMakeCollectableII;
 | 
					  IdentifierInfo *NSMakeCollectableII;
 | 
				
			||||||
 | 
					  IdentifierInfo *CFMakeCollectableII;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
  GCCollectableCallsChecker(MigrationContext &ctx, ParentMap &map)
 | 
					  GCCollectableCallsChecker(MigrationContext &ctx, ParentMap &map)
 | 
				
			||||||
    : MigrateCtx(ctx), PMap(map) {
 | 
					    : MigrateCtx(ctx), PMap(map) {
 | 
				
			||||||
    NSMakeCollectableII =
 | 
					    IdentifierTable &Ids = MigrateCtx.getPass().Ctx.Idents;
 | 
				
			||||||
        &MigrateCtx.getPass().Ctx.Idents.get("NSMakeCollectable");
 | 
					    NSMakeCollectableII = &Ids.get("NSMakeCollectable");
 | 
				
			||||||
 | 
					    CFMakeCollectableII = &Ids.get("CFMakeCollectable");
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  bool VisitCallExpr(CallExpr *E) {
 | 
					  bool VisitCallExpr(CallExpr *E) {
 | 
				
			||||||
 | 
					    TransformActions &TA = MigrateCtx.getPass().TA;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Expr *CEE = E->getCallee()->IgnoreParenImpCasts();
 | 
					    Expr *CEE = E->getCallee()->IgnoreParenImpCasts();
 | 
				
			||||||
    if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CEE)) {
 | 
					    if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CEE)) {
 | 
				
			||||||
      if (FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl())) {
 | 
					      if (FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl())) {
 | 
				
			||||||
        if (FD->getDeclContext()->getRedeclContext()->isFileContext() &&
 | 
					        if (!FD->getDeclContext()->getRedeclContext()->isFileContext())
 | 
				
			||||||
            FD->getIdentifier() == NSMakeCollectableII) {
 | 
					          return true;
 | 
				
			||||||
          TransformActions &TA = MigrateCtx.getPass().TA;
 | 
					
 | 
				
			||||||
 | 
					        if (FD->getIdentifier() == NSMakeCollectableII) {
 | 
				
			||||||
          Transaction Trans(TA);
 | 
					          Transaction Trans(TA);
 | 
				
			||||||
          TA.clearDiagnostic(diag::err_unavailable,
 | 
					          TA.clearDiagnostic(diag::err_unavailable,
 | 
				
			||||||
                             diag::err_unavailable_message,
 | 
					                             diag::err_unavailable_message,
 | 
				
			||||||
                             diag::err_ovl_deleted_call, // ObjC++
 | 
					                             diag::err_ovl_deleted_call, // ObjC++
 | 
				
			||||||
                             DRE->getSourceRange());
 | 
					                             DRE->getSourceRange());
 | 
				
			||||||
          TA.replace(DRE->getSourceRange(), "CFBridgingRelease");
 | 
					          TA.replace(DRE->getSourceRange(), "CFBridgingRelease");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        } else if (FD->getIdentifier() == CFMakeCollectableII) {
 | 
				
			||||||
 | 
					          TA.reportError("CFMakeCollectable will leak the object that it "
 | 
				
			||||||
 | 
					                         "receives in ARC", DRE->getLocation(),
 | 
				
			||||||
 | 
					                         DRE->getSourceRange());
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,11 @@
 | 
				
			||||||
 | 
					// RUN: %clang_cc1 -arcmt-check -verify -triple x86_64-apple-darwin10 -fobjc-gc-only %s
 | 
				
			||||||
 | 
					// RUN: %clang_cc1 -arcmt-check -verify -triple x86_64-apple-darwin10 -fobjc-gc-only -x objective-c++ %s
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define CF_AUTOMATED_REFCOUNT_UNAVAILABLE __attribute__((unavailable("not available in automatic reference counting mode")))
 | 
				
			||||||
 | 
					typedef const void * CFTypeRef;
 | 
				
			||||||
 | 
					CFTypeRef CFMakeCollectable(CFTypeRef cf) CF_AUTOMATED_REFCOUNT_UNAVAILABLE; // expected-note {{unavailable}}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void test1(CFTypeRef *cft) {
 | 
				
			||||||
 | 
					  CFTypeRef c = CFMakeCollectable(cft); // expected-error {{CFMakeCollectable will leak the object that it receives in ARC}} \
 | 
				
			||||||
 | 
					                // expected-error {{unavailable}}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Loading…
	
		Reference in New Issue