aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td3
-rw-r--r--lib/Sema/SemaExpr.cpp10
-rw-r--r--test/SemaObjC/arc.m15
3 files changed, 28 insertions, 0 deletions
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index b608a5d694..9d35438975 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -2815,6 +2815,9 @@ def err_typecheck_member_reference_struct_union : Error<
"member reference base type %0 is not a structure or union">;
def err_typecheck_member_reference_ivar : Error<
"%0 does not have a member named %1">;
+def error_arc_weak_ivar_access : Error<
+ "dereferencing a __weak pointer is not allowed due to possible "
+ "null value caused by race condition, assign it to strong variable first">;
def err_typecheck_member_reference_arrow : Error<
"member reference type %0 is not a pointer">;
def err_typecheck_member_reference_suggestion : Error<
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 3122d42cdb..5e30e7179c 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -4333,6 +4333,16 @@ Sema::LookupMemberExpr(LookupResult &R, ExprResult &BaseExpr,
Diag(MemberLoc, diag::error_protected_ivar_access)
<< IV->getDeclName();
}
+ if (getLangOptions().ObjCAutoRefCount) {
+ Expr *BaseExp = BaseExpr.get()->IgnoreParenImpCasts();
+ if (UnaryOperator *UO = dyn_cast<UnaryOperator>(BaseExp))
+ if (UO->getOpcode() == UO_Deref)
+ BaseExp = UO->getSubExpr()->IgnoreParenCasts();
+
+ if (DeclRefExpr *DE = dyn_cast<DeclRefExpr>(BaseExp))
+ if (DE->getType().getObjCLifetime() == Qualifiers::OCL_Weak)
+ Diag(DE->getLocation(), diag::error_arc_weak_ivar_access);
+ }
return Owned(new (Context) ObjCIvarRefExpr(IV, IV->getType(),
MemberLoc, BaseExpr.take(),
diff --git a/test/SemaObjC/arc.m b/test/SemaObjC/arc.m
index fa3a06183e..4c2ae236ac 100644
--- a/test/SemaObjC/arc.m
+++ b/test/SemaObjC/arc.m
@@ -548,3 +548,18 @@ int Test31() {
int k = (pcls->isa ? i : j); // expected-error {{member reference base type 'Class<PTest31>' is not a structure or union}}
return cls->isa ? i : j; // expected-error {{member reference base type 'Class' is not a structure or union}}
}
+
+// rdar://9612030
+@interface ITest32 {
+@public
+ id ivar;
+}
+@end
+
+id Test32(__weak ITest32 *x) {
+ __weak ITest32 *y;
+ x->ivar = 0; // expected-error {{dereferencing a __weak pointer is not allowed}}
+ return y ? y->ivar // expected-error {{dereferencing a __weak pointer is not allowed}}
+ : (*x).ivar; // expected-error {{dereferencing a __weak pointer is not allowed}}
+}
+