[cfe-commits] r133806 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td include/clang/Sema/Sema.h lib/Sema/SemaChecking.cpp lib/Sema/SemaExpr.cpp test/SemaObjC/arc-unsafe-assigns.m test/SemaObjC/arc.m
Fariborz Jahanian
fjahanian at apple.com
Fri Jun 24 11:25:34 PDT 2011
Author: fjahanian
Date: Fri Jun 24 13:25:34 2011
New Revision: 133806
URL: http://llvm.org/viewvc/llvm-project?rev=133806&view=rev
Log:
objc-arc: Check on a variety of unsafe assignment of retained
objects. // rdar://9495837
Added:
cfe/trunk/test/SemaObjC/arc-unsafe-assigns.m
Modified:
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/lib/Sema/SemaChecking.cpp
cfe/trunk/lib/Sema/SemaExpr.cpp
cfe/trunk/test/SemaObjC/arc.m
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=133806&r1=133805&r2=133806&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Fri Jun 24 13:25:34 2011
@@ -2603,6 +2603,9 @@
def warn_arc_retained_assign : Warning<
"assigning retained object to %select{weak|unsafe_unretained}0 variable">,
InGroup<ARCUnsafeRetainedAssign>;
+def warn_arc_retained_property_assign : Warning<
+ "assigning retained object to unsafe property">,
+ InGroup<ARCUnsafeRetainedAssign>;
def warn_arc_trivial_member_function_with_object_member : Warning<
"%0 cannot be shared between ARC and non-ARC "
"code; add a non-trivial %select{copy constructor|copy assignment operator|"
Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=133806&r1=133805&r2=133806&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Fri Jun 24 13:25:34 2011
@@ -5644,9 +5644,13 @@
void checkRetainCycles(ObjCMessageExpr *msg);
void checkRetainCycles(Expr *receiver, Expr *argument);
- /// checkWeakUnsafeAssigns - Check whether +1 expr is being assigned
- /// to weak/__unsafe_unretained.
- void checkUnsafeAssigns(SourceLocation Loc, QualType LHS, Expr *RHS);
+ /// checkUnsafeAssigns - Check whether +1 expr is being assigned
+ /// to weak/__unsafe_unretained type.
+ bool checkUnsafeAssigns(SourceLocation Loc, QualType LHS, Expr *RHS);
+
+ /// checkUnsafeExprAssigns - Check whether +1 expr is being assigned
+ /// to weak/__unsafe_unretained expression.
+ void checkUnsafeExprAssigns(SourceLocation Loc, Expr *LHS, Expr *RHS);
/// CheckMessageArgumentTypes - Check types in an Obj-C message send.
/// \param Method - May be null.
Modified: cfe/trunk/lib/Sema/SemaChecking.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=133806&r1=133805&r2=133806&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaChecking.cpp (original)
+++ cfe/trunk/lib/Sema/SemaChecking.cpp Fri Jun 24 13:25:34 2011
@@ -3720,15 +3720,50 @@
diagnoseRetainCycle(*this, capturer, owner);
}
-void Sema::checkUnsafeAssigns(SourceLocation Loc,
+bool Sema::checkUnsafeAssigns(SourceLocation Loc,
QualType LHS, Expr *RHS) {
Qualifiers::ObjCLifetime LT = LHS.getObjCLifetime();
if (LT != Qualifiers::OCL_Weak && LT != Qualifiers::OCL_ExplicitNone)
- return;
- if (ImplicitCastExpr *cast = dyn_cast<ImplicitCastExpr>(RHS))
- if (cast->getCastKind() == CK_ObjCConsumeObject)
+ return false;
+ // strip off any implicit cast added to get to the one arc-specific
+ while (ImplicitCastExpr *cast = dyn_cast<ImplicitCastExpr>(RHS)) {
+ if (cast->getCastKind() == CK_ObjCConsumeObject) {
Diag(Loc, diag::warn_arc_retained_assign)
<< (LT == Qualifiers::OCL_ExplicitNone)
<< RHS->getSourceRange();
+ return true;
+ }
+ RHS = cast->getSubExpr();
+ }
+ return false;
}
+void Sema::checkUnsafeExprAssigns(SourceLocation Loc,
+ Expr *LHS, Expr *RHS) {
+ QualType LHSType = LHS->getType();
+ if (checkUnsafeAssigns(Loc, LHSType, RHS))
+ return;
+ Qualifiers::ObjCLifetime LT = LHSType.getObjCLifetime();
+ // FIXME. Check for other life times.
+ if (LT != Qualifiers::OCL_None)
+ return;
+
+ if (ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(LHS)) {
+ if (PRE->isImplicitProperty())
+ return;
+ const ObjCPropertyDecl *PD = PRE->getExplicitProperty();
+ if (!PD)
+ return;
+
+ unsigned Attributes = PD->getPropertyAttributes();
+ if (Attributes & ObjCPropertyDecl::OBJC_PR_assign)
+ while (ImplicitCastExpr *cast = dyn_cast<ImplicitCastExpr>(RHS)) {
+ if (cast->getCastKind() == CK_ObjCConsumeObject) {
+ Diag(Loc, diag::warn_arc_retained_property_assign)
+ << RHS->getSourceRange();
+ return;
+ }
+ RHS = cast->getSubExpr();
+ }
+ }
+}
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=133806&r1=133805&r2=133806&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Fri Jun 24 13:25:34 2011
@@ -6735,8 +6735,8 @@
if (ConvTy == Compatible) {
if (LHSType.getObjCLifetime() == Qualifiers::OCL_Strong)
checkRetainCycles(LHS, RHS.get());
- else
- checkUnsafeAssigns(Loc, LHSType, RHS.get());
+ else if (getLangOptions().ObjCAutoRefCount)
+ checkUnsafeExprAssigns(Loc, LHS, RHS.get());
}
} else {
// Compound assignment "x += y"
Added: cfe/trunk/test/SemaObjC/arc-unsafe-assigns.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/arc-unsafe-assigns.m?rev=133806&view=auto
==============================================================================
--- cfe/trunk/test/SemaObjC/arc-unsafe-assigns.m (added)
+++ cfe/trunk/test/SemaObjC/arc-unsafe-assigns.m Fri Jun 24 13:25:34 2011
@@ -0,0 +1,41 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fobjc-nonfragile-abi -fsyntax-only -fobjc-arc -verify %s
+// rdar://9495837
+
+ at interface Foo {
+ __unsafe_unretained id unsafe_ivar;
+}
+
+ at property (assign,nonatomic) id unsafe_prop;
+
+- (id)init;
++ (id)new;
++ (id)alloc;
+
+-(void)Meth;
+ at end
+
+ at implementation Foo
+ at synthesize unsafe_prop;
+-(id)init { return self; }
++(id)new { return 0; }
++(id)alloc { return 0; }
+
+-(void)Meth {
+ self.unsafe_prop = [Foo new]; // expected-warning {{assigning retained object to unsafe property}}
+ self->unsafe_ivar = [Foo new]; // expected-warning {{assigning retained object to unsafe_unretained}}
+ self.unsafe_prop = [[Foo alloc] init]; // expected-warning {{assigning retained object to unsafe property}}
+ self->unsafe_ivar = [[Foo alloc] init]; // expected-warning {{assigning retained object to unsafe_unretained}}
+
+ __unsafe_unretained id unsafe_var;
+ unsafe_var = [Foo new]; // expected-warning {{assigning retained object to unsafe_unretained}}
+ unsafe_var = [[Foo alloc] init]; // expected-warning {{assigning retained object to unsafe_unretained}}
+}
+ at end
+
+void bar(Foo *f) {
+ f.unsafe_prop = [Foo new]; // expected-warning {{assigning retained object to unsafe property}}
+
+ __unsafe_unretained id unsafe_var;
+ unsafe_var = [Foo new]; // expected-warning {{assigning retained object to unsafe_unretained}}
+ unsafe_var = [[Foo alloc] init]; // expected-warning {{assigning retained object to unsafe_unretained}}
+}
Modified: cfe/trunk/test/SemaObjC/arc.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/arc.m?rev=133806&r1=133805&r2=133806&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/arc.m (original)
+++ cfe/trunk/test/SemaObjC/arc.m Fri Jun 24 13:25:34 2011
@@ -518,12 +518,12 @@
// rdar://9495837
@interface Test30
-- (id) new;
++ (id) new;
- (void)Meth;
@end
@implementation Test30
-- (id) new { return 0; }
++ (id) new { return 0; }
- (void) Meth {
__weak id x = [Test30 new]; // expected-warning {{assigning retained object to weak variable}}
id __unsafe_unretained u = [Test30 new]; // expected-warning {{assigning retained object to unsafe_unretained variable}}
More information about the cfe-commits
mailing list