r210660 - Objective-C. Patch to handle bridge attribute warnings
Fariborz Jahanian
fjahanian at apple.com
Wed Jun 11 09:52:44 PDT 2014
Author: fjahanian
Date: Wed Jun 11 11:52:44 2014
New Revision: 210660
URL: http://llvm.org/viewvc/llvm-project?rev=210660&view=rev
Log:
Objective-C. Patch to handle bridge attribute warnings
correctly when both NSAttributedString and
NSMutableAttributedString are specified on the same
CFStruct via different typedefs. // rdar://17238954
Added:
cfe/trunk/test/SemaObjC/objc-mixed-bridge-attribute.m
Modified:
cfe/trunk/lib/Sema/SemaExprObjC.cpp
Modified: cfe/trunk/lib/Sema/SemaExprObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprObjC.cpp?rev=210660&r1=210659&r2=210660&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprObjC.cpp Wed Jun 11 11:52:44 2014
@@ -3280,12 +3280,15 @@ diagnoseObjCARCConversion(Sema &S, Sourc
}
template <typename TB>
-static void CheckObjCBridgeNSCast(Sema &S, QualType castType, Expr *castExpr) {
+static bool CheckObjCBridgeNSCast(Sema &S, QualType castType, Expr *castExpr,
+ bool &HadTheAttribute, bool warn) {
QualType T = castExpr->getType();
+ HadTheAttribute = false;
while (const TypedefType *TD = dyn_cast<TypedefType>(T.getTypePtr())) {
TypedefNameDecl *TDNDecl = TD->getDecl();
if (TB *ObjCBAttr = getObjCBridgeAttr<TB>(TD)) {
if (IdentifierInfo *Parm = ObjCBAttr->getBridgedType()) {
+ HadTheAttribute = true;
NamedDecl *Target = nullptr;
// Check for an existing type with this name.
LookupResult R(S, DeclarationName(Parm), SourceLocation(),
@@ -3300,23 +3303,26 @@ static void CheckObjCBridgeNSCast(Sema &
= InterfacePointerType->getObjectType()->getInterface();
if ((CastClass == ExprClass) ||
(CastClass && ExprClass->isSuperClassOf(CastClass)))
- return;
- S.Diag(castExpr->getLocStart(), diag::warn_objc_invalid_bridge)
- << T << Target->getName() << castType->getPointeeType();
- return;
+ return true;
+ if (warn)
+ S.Diag(castExpr->getLocStart(), diag::warn_objc_invalid_bridge)
+ << T << Target->getName() << castType->getPointeeType();
+ return false;
} else if (castType->isObjCIdType() ||
(S.Context.ObjCObjectAdoptsQTypeProtocols(
castType, ExprClass)))
// ok to cast to 'id'.
// casting to id<p-list> is ok if bridge type adopts all of
// p-list protocols.
- return;
+ return true;
else {
- S.Diag(castExpr->getLocStart(), diag::warn_objc_invalid_bridge)
- << T << Target->getName() << castType;
- S.Diag(TDNDecl->getLocStart(), diag::note_declared_at);
- S.Diag(Target->getLocStart(), diag::note_declared_at);
- return;
+ if (warn) {
+ S.Diag(castExpr->getLocStart(), diag::warn_objc_invalid_bridge)
+ << T << Target->getName() << castType;
+ S.Diag(TDNDecl->getLocStart(), diag::note_declared_at);
+ S.Diag(Target->getLocStart(), diag::note_declared_at);
+ }
+ return false;
}
}
}
@@ -3325,20 +3331,25 @@ static void CheckObjCBridgeNSCast(Sema &
S.Diag(TDNDecl->getLocStart(), diag::note_declared_at);
if (Target)
S.Diag(Target->getLocStart(), diag::note_declared_at);
+ return true;
}
- return;
+ return false;
}
T = TDNDecl->getUnderlyingType();
}
+ return true;
}
template <typename TB>
-static void CheckObjCBridgeCFCast(Sema &S, QualType castType, Expr *castExpr) {
+static bool CheckObjCBridgeCFCast(Sema &S, QualType castType, Expr *castExpr,
+ bool &HadTheAttribute, bool warn) {
QualType T = castType;
+ HadTheAttribute = false;
while (const TypedefType *TD = dyn_cast<TypedefType>(T.getTypePtr())) {
TypedefNameDecl *TDNDecl = TD->getDecl();
if (TB *ObjCBAttr = getObjCBridgeAttr<TB>(TD)) {
if (IdentifierInfo *Parm = ObjCBAttr->getBridgedType()) {
+ HadTheAttribute = true;
NamedDecl *Target = nullptr;
// Check for an existing type with this name.
LookupResult R(S, DeclarationName(Parm), SourceLocation(),
@@ -3353,24 +3364,28 @@ static void CheckObjCBridgeCFCast(Sema &
= InterfacePointerType->getObjectType()->getInterface();
if ((CastClass == ExprClass) ||
(ExprClass && CastClass->isSuperClassOf(ExprClass)))
- return;
- S.Diag(castExpr->getLocStart(), diag::warn_objc_invalid_bridge_to_cf)
- << castExpr->getType()->getPointeeType() << T;
- S.Diag(TDNDecl->getLocStart(), diag::note_declared_at);
- return;
+ return true;
+ if (warn) {
+ S.Diag(castExpr->getLocStart(), diag::warn_objc_invalid_bridge_to_cf)
+ << castExpr->getType()->getPointeeType() << T;
+ S.Diag(TDNDecl->getLocStart(), diag::note_declared_at);
+ }
+ return false;
} else if (castExpr->getType()->isObjCIdType() ||
(S.Context.QIdProtocolsAdoptObjCObjectProtocols(
castExpr->getType(), CastClass)))
// ok to cast an 'id' expression to a CFtype.
// ok to cast an 'id<plist>' expression to CFtype provided plist
// adopts all of CFtype's ObjetiveC's class plist.
- return;
+ return true;
else {
- S.Diag(castExpr->getLocStart(), diag::warn_objc_invalid_bridge_to_cf)
- << castExpr->getType() << castType;
- S.Diag(TDNDecl->getLocStart(), diag::note_declared_at);
- S.Diag(Target->getLocStart(), diag::note_declared_at);
- return;
+ if (warn) {
+ S.Diag(castExpr->getLocStart(), diag::warn_objc_invalid_bridge_to_cf)
+ << castExpr->getType() << castType;
+ S.Diag(TDNDecl->getLocStart(), diag::note_declared_at);
+ S.Diag(Target->getLocStart(), diag::note_declared_at);
+ }
+ return false;
}
}
}
@@ -3379,11 +3394,13 @@ static void CheckObjCBridgeCFCast(Sema &
S.Diag(TDNDecl->getLocStart(), diag::note_declared_at);
if (Target)
S.Diag(Target->getLocStart(), diag::note_declared_at);
+ return true;
}
- return;
+ return false;
}
T = TDNDecl->getUnderlyingType();
}
+ return true;
}
void Sema::CheckTollFreeBridgeCast(QualType castType, Expr *castExpr) {
@@ -3393,12 +3410,46 @@ void Sema::CheckTollFreeBridgeCast(QualT
ARCConversionTypeClass exprACTC = classifyTypeForARCConversion(castExpr->getType());
ARCConversionTypeClass castACTC = classifyTypeForARCConversion(castType);
if (castACTC == ACTC_retainable && exprACTC == ACTC_coreFoundation) {
- CheckObjCBridgeNSCast<ObjCBridgeAttr>(*this, castType, castExpr);
- CheckObjCBridgeNSCast<ObjCBridgeMutableAttr>(*this, castType, castExpr);
+ bool HasObjCBridgeAttr;
+ bool ObjCBridgeAttrWillNotWarn =
+ CheckObjCBridgeNSCast<ObjCBridgeAttr>(*this, castType, castExpr, HasObjCBridgeAttr,
+ false);
+ if (ObjCBridgeAttrWillNotWarn && HasObjCBridgeAttr)
+ return;
+ bool HasObjCBridgeMutableAttr;
+ bool ObjCBridgeMutableAttrWillNotWarn =
+ CheckObjCBridgeNSCast<ObjCBridgeMutableAttr>(*this, castType, castExpr,
+ HasObjCBridgeMutableAttr, false);
+ if (ObjCBridgeMutableAttrWillNotWarn && HasObjCBridgeMutableAttr)
+ return;
+
+ if (HasObjCBridgeAttr)
+ CheckObjCBridgeNSCast<ObjCBridgeAttr>(*this, castType, castExpr, HasObjCBridgeAttr,
+ true);
+ else if (HasObjCBridgeMutableAttr)
+ CheckObjCBridgeNSCast<ObjCBridgeMutableAttr>(*this, castType, castExpr,
+ HasObjCBridgeMutableAttr, true);
}
else if (castACTC == ACTC_coreFoundation && exprACTC == ACTC_retainable) {
- CheckObjCBridgeCFCast<ObjCBridgeAttr>(*this, castType, castExpr);
- CheckObjCBridgeCFCast<ObjCBridgeMutableAttr>(*this, castType, castExpr);
+ bool HasObjCBridgeAttr;
+ bool ObjCBridgeAttrWillNotWarn =
+ CheckObjCBridgeCFCast<ObjCBridgeAttr>(*this, castType, castExpr, HasObjCBridgeAttr,
+ false);
+ if (ObjCBridgeAttrWillNotWarn && HasObjCBridgeAttr)
+ return;
+ bool HasObjCBridgeMutableAttr;
+ bool ObjCBridgeMutableAttrWillNotWarn =
+ CheckObjCBridgeCFCast<ObjCBridgeMutableAttr>(*this, castType, castExpr,
+ HasObjCBridgeMutableAttr, false);
+ if (ObjCBridgeMutableAttrWillNotWarn && HasObjCBridgeMutableAttr)
+ return;
+
+ if (HasObjCBridgeAttr)
+ CheckObjCBridgeCFCast<ObjCBridgeAttr>(*this, castType, castExpr, HasObjCBridgeAttr,
+ true);
+ else if (HasObjCBridgeMutableAttr)
+ CheckObjCBridgeCFCast<ObjCBridgeMutableAttr>(*this, castType, castExpr,
+ HasObjCBridgeMutableAttr, true);
}
}
Added: cfe/trunk/test/SemaObjC/objc-mixed-bridge-attribute.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/objc-mixed-bridge-attribute.m?rev=210660&view=auto
==============================================================================
--- cfe/trunk/test/SemaObjC/objc-mixed-bridge-attribute.m (added)
+++ cfe/trunk/test/SemaObjC/objc-mixed-bridge-attribute.m Wed Jun 11 11:52:44 2014
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s
+// expected-no-diagnostics
+// rdar://17238954
+
+typedef const struct __attribute__((objc_bridge(NSAttributedString))) __CFAttributedString *CFAttributedStringRef;
+
+typedef struct __attribute__((objc_bridge_mutable(NSMutableAttributedString))) __CFAttributedString *CFMutableAttributedStringRef;
+
+ at interface NSAttributedString
+ at end
+
+ at interface NSMutableAttributedString
+ at end
+
+struct __CFAttributedString {
+};
+
+void Test1(CFAttributedStringRef attrStr)
+{
+ id x = (NSAttributedString *) attrStr; // no warning
+}
+
+void Test2(NSAttributedString *attrStr) {
+ CFAttributedStringRef cfsr = (CFAttributedStringRef) attrStr;
+}
+
More information about the cfe-commits
mailing list