summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2013-11-16 01:45:25 +0000
committerFariborz Jahanian <fjahanian@apple.com>2013-11-16 01:45:25 +0000
commitf07183ce9402cb11de96bdb253806b15b0c6295a (patch)
tree983c5eb4a7a983435d4fdc50256e3b622c2059eb /clang/lib/Sema
parentb37c431d53b3e5c7e015c97fa1c3ad528662cade (diff)
downloadbcm5719-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.cpp29
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;
}
OpenPOWER on IntegriCloud