summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
Diffstat (limited to 'clang')
-rw-r--r--clang/include/clang/Basic/DiagnosticGroups.td1
-rw-r--r--clang/include/clang/Basic/DiagnosticSemaKinds.td5
-rw-r--r--clang/lib/Sema/SemaExprObjC.cpp21
-rw-r--r--clang/test/SemaObjC/arc-cfbridge-warning.m41
4 files changed, 63 insertions, 5 deletions
diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td
index 7a813b08a8b..0f25a1523b0 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -422,6 +422,7 @@ def : DiagGroup<"arc-abi">;
def ARCUnsafeRetainedAssign : DiagGroup<"arc-unsafe-retained-assign">;
def ARCRetainCycles : DiagGroup<"arc-retain-cycles">;
def ARCNonPodMemAccess : DiagGroup<"arc-non-pod-memaccess">;
+def ARCBridgeCastRelease : DiagGroup<"arc-bridge-cast-release">;
def AutomaticReferenceCounting : DiagGroup<"arc",
[ARCUnsafeRetainedAssign,
ARCRetainCycles,
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index fe878725a81..d059e870bbb 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -4459,6 +4459,11 @@ def note_arc_retain_cycle_owner : Note<
def warn_arc_object_memaccess : Warning<
"%select{destination for|source of}0 this %1 call is a pointer to "
"ownership-qualified type %2">, InGroup<ARCNonPodMemAccess>;
+
+def warn_arc_consumed_object_released : Warning<
+ "__bridge cast of collection literal of type %1 to \"bridgeable\" C "
+ "type %0 causes early release of the collection">,
+ InGroup<ARCBridgeCastRelease>;
let CategoryName = "ARC and @properties" in {
diff --git a/clang/lib/Sema/SemaExprObjC.cpp b/clang/lib/Sema/SemaExprObjC.cpp
index 40ab95b6ec5..5746e732943 100644
--- a/clang/lib/Sema/SemaExprObjC.cpp
+++ b/clang/lib/Sema/SemaExprObjC.cpp
@@ -4075,11 +4075,22 @@ ExprResult Sema::BuildObjCBridgedCast(SourceLocation LParenLoc,
// Okay: id -> CF
CK = CK_BitCast;
switch (Kind) {
- case OBC_Bridge:
- // Reclaiming a value that's going to be __bridge-casted to CF
- // is very dangerous, so we don't do it.
- SubExpr = maybeUndoReclaimObject(SubExpr);
- break;
+ case OBC_Bridge: {
+ const ImplicitCastExpr *implCE = dyn_cast<ImplicitCastExpr>(SubExpr);
+ while (implCE && implCE->getCastKind() == CK_BitCast)
+ implCE = dyn_cast<ImplicitCastExpr>(implCE->getSubExpr());
+ if (implCE && (implCE->getCastKind() == CK_ARCConsumeObject))
+ if (const Expr *LitExp = implCE->getSubExpr())
+ if ((isa<ObjCArrayLiteral>(LitExp) ||
+ isa<ObjCDictionaryLiteral>(LitExp)) &&
+ T->isCARCBridgableType())
+ Diag(BridgeKeywordLoc, diag::warn_arc_consumed_object_released)
+ << T << implCE->getType();
+ // Reclaiming a value that's going to be __bridge-casted to CF
+ // is very dangerous, so we don't do it.
+ SubExpr = maybeUndoReclaimObject(SubExpr);
+ break;
+ }
case OBC_BridgeRetained:
// Produce the object before casting it.
diff --git a/clang/test/SemaObjC/arc-cfbridge-warning.m b/clang/test/SemaObjC/arc-cfbridge-warning.m
new file mode 100644
index 00000000000..142983f1dec
--- /dev/null
+++ b/clang/test/SemaObjC/arc-cfbridge-warning.m
@@ -0,0 +1,41 @@
+// RUN: %clang_cc1 -fsyntax-only -x objective-c -fobjc-arc -verify -Wno-objc-root-class %s
+// rdar://18768214
+
+
+@class NSArray;
+typedef const struct __attribute__((objc_bridge(NSArray))) __CFArray * CFArrayRef;
+@class NSString;
+typedef const void * CFTypeRef;
+
+typedef const struct __attribute__((objc_bridge(NSString))) __CFString * CFStringRef;
+
+typedef long NSInteger;
+typedef unsigned long NSUInteger;
+
+@interface NSObject {
+ Class isa __attribute__((deprecated));
+}
++ (void)initialize;
+- (instancetype)init;
++ (instancetype)new;
++ (instancetype)alloc;
+- (void)dealloc;
+@end
+
+@interface NSArray : NSObject
+@property (readonly) NSUInteger count;
+- (id)objectAtIndex:(NSUInteger)index;
+- (instancetype)init __attribute__((objc_designated_initializer));
+- (instancetype)initWithObjects:(const id [])objects count:(NSUInteger)cnt __attribute__((objc_designated_initializer));
++ (instancetype)array;
++ (instancetype)arrayWithObject:(id)anObject;
++ (instancetype)arrayWithObjects:(const id [])objects count:(NSUInteger)cnt;
++ (instancetype)arrayWithObjects:(id)firstObj, ... __attribute__((sentinel(0,1)));
+@end
+
+static CFStringRef _s;
+
+CFArrayRef _array()
+{
+ return (__bridge CFArrayRef)@[(__bridge NSString *)_s]; // expected-warning {{__bridge cast of collection literal of type 'NSArray *' to "bridgeable" C type 'CFArrayRef' (aka 'const struct __CFArray *') causes early release of the collection}}
+}
OpenPOWER on IntegriCloud