diff options
| author | Fariborz Jahanian <fjahanian@apple.com> | 2013-11-16 01:45:25 +0000 |
|---|---|---|
| committer | Fariborz Jahanian <fjahanian@apple.com> | 2013-11-16 01:45:25 +0000 |
| commit | f07183ce9402cb11de96bdb253806b15b0c6295a (patch) | |
| tree | 983c5eb4a7a983435d4fdc50256e3b622c2059eb /clang/lib/Sema | |
| parent | b37c431d53b3e5c7e015c97fa1c3ad528662cade (diff) | |
| download | bcm5719-llvm-f07183ce9402cb11de96bdb253806b15b0c6295a.tar.gz bcm5719-llvm-f07183ce9402cb11de96bdb253806b15b0c6295a.zip | |
ObjetiveC ARC. Start diagnosing invalid toll free bridging.
// rdar://15454846.
llvm-svn: 194915
Diffstat (limited to 'clang/lib/Sema')
| -rw-r--r-- | clang/lib/Sema/SemaExprObjC.cpp | 29 |
1 files changed, 19 insertions, 10 deletions
diff --git a/clang/lib/Sema/SemaExprObjC.cpp b/clang/lib/Sema/SemaExprObjC.cpp index e72519c3edf..f226af3ae0a 100644 --- a/clang/lib/Sema/SemaExprObjC.cpp +++ b/clang/lib/Sema/SemaExprObjC.cpp @@ -3172,23 +3172,32 @@ static bool CheckObjCBridgeCast(Sema &S, QualType castType, Expr *castExpr) { if (TDNDecl->hasAttr<ObjCBridgeAttr>()) { ObjCBridgeAttr *ObjCBAttr = TDNDecl->getAttr<ObjCBridgeAttr>(); IdentifierInfo *Parm = ObjCBAttr->getBridgedType(); + NamedDecl *Target = 0; if (Parm && S.getLangOpts().ObjC1) { // Check for an existing type with this name. LookupResult R(S, DeclarationName(Parm), SourceLocation(), Sema::LookupOrdinaryName); if (S.LookupName(R, S.TUScope)) { - NamedDecl *Target = R.getFoundDecl(); - if (Target && !isa<ObjCInterfaceDecl>(Target)) { - S.Diag(castExpr->getLocStart(), diag::err_objc_bridged_not_interface) - << castExpr->getType() << Parm->getName(); - S.Diag(TDNDecl->getLocStart(), diag::note_declared_at); - S.Diag(Target->getLocStart(), diag::note_declared_at); + Target = R.getFoundDecl(); + if (Target && isa<ObjCInterfaceDecl>(Target)) { + ObjCInterfaceDecl *ExprClass = cast<ObjCInterfaceDecl>(Target); + if (const ObjCObjectPointerType *InterfacePointerType = + castType->getAsObjCInterfacePointerType()) { + ObjCInterfaceDecl *CastClass + = InterfacePointerType->getObjectType()->getInterface(); + if ((CastClass == ExprClass) || (CastClass && ExprClass->isSuperClassOf(CastClass))) + return true; + S.Diag(castExpr->getLocStart(), diag::warn_objc_invalid_bridge) + << TDNDecl->getName() << Target->getName() << CastClass->getName(); + return true; + } } - } else { - S.Diag(castExpr->getLocStart(), diag::err_objc_bridged_not_interface) - << castExpr->getType() << Parm->getName(); - S.Diag(TDNDecl->getLocStart(), diag::note_declared_at); } + S.Diag(castExpr->getLocStart(), diag::err_objc_bridged_not_interface) + << castExpr->getType() << Parm->getName(); + S.Diag(TDNDecl->getLocStart(), diag::note_declared_at); + if (Target) + S.Diag(Target->getLocStart(), diag::note_declared_at); } return true; } |

