bkelley created this revision.
After examining the remaining uses of LangOptions.ObjCAutoRefCount, found a
some additional places to also check for ObjCWeak not covered by previous test
cases. Added a test file to verify all the code paths that were changed.
https://reviews.llvm.org/D31007
Files:
lib/Sema/SemaCast.cpp
lib/Sema/SemaDecl.cpp
lib/Sema/SemaDeclCXX.cpp
lib/Sema/SemaInit.cpp
test/SemaObjCXX/objc-weak.mm
Index: test/SemaObjCXX/objc-weak.mm
===================================================================
--- /dev/null
+++ test/SemaObjCXX/objc-weak.mm
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -fsyntax-only -fobjc-runtime-has-weak -fobjc-weak -fblocks -Wno-objc-root-class -std=c++98 -Wno-c++0x-extensions -verify %s
+
+@interface AnObject
+@property(weak) id value;
+@end
+
+__attribute__((objc_arc_weak_reference_unavailable))
+@interface NOWEAK : AnObject // expected-note 2 {{class is declared here}}
+@end
+
+struct S {
+ __weak id a; // expected-note {{because type 'S' has a member with __weak ownership}}
+};
+
+union U {
+ __weak id a; // expected-error {{ARC forbids Objective-C objects in union}}
+ S b; // expected-error {{union member 'b' has a non-trivial copy constructor}}
+};
+
+void testCast(AnObject *o) {
+ __weak id a = reinterpret_cast<__weak NOWEAK *>(o); // expected-error {{class is incompatible with __weak references}} \
+ // expected-error {{explicit ownership qualifier on cast result has no effect}} \
+ // expected-error {{assignment of a weak-unavailable object to a __weak object}}
+
+ __weak id b = static_cast<__weak NOWEAK *>(o); // expected-error {{class is incompatible with __weak references}} \
+ // expected-error {{explicit ownership qualifier on cast result has no effect}} \
+ // expected-error {{assignment of a weak-unavailable object to a __weak object}}
+}
Index: lib/Sema/SemaInit.cpp
===================================================================
--- lib/Sema/SemaInit.cpp
+++ lib/Sema/SemaInit.cpp
@@ -6680,6 +6680,8 @@
// full-expression's cleanups.
if ((S.getLangOpts().ObjCAutoRefCount &&
MTE->getType()->isObjCLifetimeType()) ||
+ (S.getLangOpts().ObjCWeak &&
+ MTE->getType().getObjCLifetime() == Qualifiers::OCL_Weak) ||
(MTE->getStorageDuration() == SD_Automatic &&
MTE->getType().isDestructedType()))
S.Cleanup.setExprNeedsCleanups(true);
Index: lib/Sema/SemaDeclCXX.cpp
===================================================================
--- lib/Sema/SemaDeclCXX.cpp
+++ lib/Sema/SemaDeclCXX.cpp
@@ -7150,8 +7150,10 @@
// [...] nontrivally ownership-qualified types are [...] not trivially
// default constructible, copy constructible, move constructible, copy
// assignable, move assignable, or destructible [...]
- if (S.getLangOpts().ObjCAutoRefCount &&
- FieldType.hasNonTrivialObjCLifetime()) {
+ if ((S.getLangOpts().ObjCAutoRefCount &&
+ FieldType.hasNonTrivialObjCLifetime()) ||
+ (S.getLangOpts().ObjCWeak &&
+ FieldType.getObjCLifetime() == Qualifiers::OCL_Weak)) {
if (Diagnose)
S.Diag(FI->getLocation(), diag::note_nontrivial_objc_ownership)
<< RD << FieldType.getObjCLifetime();
Index: lib/Sema/SemaDecl.cpp
===================================================================
--- lib/Sema/SemaDecl.cpp
+++ lib/Sema/SemaDecl.cpp
@@ -14493,7 +14493,7 @@
// Verify that all the fields are okay.
SmallVector<FieldDecl*, 32> RecFields;
- bool ARCErrReported = false;
+ bool ObjCFieldLifetimeErrReported = false;
for (ArrayRef<Decl *>::iterator i = Fields.begin(), end = Fields.end();
i != end; ++i) {
FieldDecl *FD = cast<FieldDecl>(*i);
@@ -14628,16 +14628,20 @@
<< FixItHint::CreateInsertion(FD->getLocation(), "*");
QualType T = Context.getObjCObjectPointerType(FD->getType());
FD->setType(T);
- } else if (getLangOpts().ObjCAutoRefCount && Record && !ARCErrReported &&
+ } else if ((getLangOpts().ObjCAutoRefCount || getLangOpts().ObjCWeak) &&
+ Record && !ObjCFieldLifetimeErrReported &&
(!getLangOpts().CPlusPlus || Record->isUnion())) {
- // It's an error in ARC if a field has lifetime.
+ // It's an error in ARC or Weak if a field has lifetime.
// We don't want to report this in a system header, though,
// so we just make the field unavailable.
// FIXME: that's really not sufficient; we need to make the type
// itself invalid to, say, initialize or copy.
QualType T = FD->getType();
Qualifiers::ObjCLifetime lifetime = T.getObjCLifetime();
- if (lifetime && lifetime != Qualifiers::OCL_ExplicitNone) {
+ if (lifetime &&
+ ((getLangOpts().ObjCAutoRefCount &&
+ lifetime != Qualifiers::OCL_ExplicitNone) ||
+ (getLangOpts().ObjCWeak && lifetime == Qualifiers::OCL_Weak))) {
SourceLocation loc = FD->getLocation();
if (getSourceManager().isInSystemHeader(loc)) {
if (!FD->hasAttr<UnavailableAttr>()) {
@@ -14648,7 +14652,7 @@
Diag(FD->getLocation(), diag::err_arc_objc_object_in_tag)
<< T->isBlockPointerType() << Record->getTagKind();
}
- ARCErrReported = true;
+ ObjCFieldLifetimeErrReported = true;
}
} else if (getLangOpts().ObjC1 &&
getLangOpts().getGC() != LangOptions::NonGC &&
Index: lib/Sema/SemaCast.cpp
===================================================================
--- lib/Sema/SemaCast.cpp
+++ lib/Sema/SemaCast.cpp
@@ -872,7 +872,7 @@
}
SrcExpr = ExprError();
} else if (tcr == TC_Success) {
- if (Self.getLangOpts().ObjCAutoRefCount)
+ if (Self.getLangOpts().ObjCAutoRefCount || Self.getLangOpts().ObjCWeak)
checkObjCConversion(Sema::CCK_OtherCast);
DiagnoseReinterpretUpDownCast(Self, SrcExpr.get(), DestType, OpRange);
}
@@ -936,7 +936,7 @@
} else if (tcr == TC_Success) {
if (Kind == CK_BitCast)
checkCastAlign();
- if (Self.getLangOpts().ObjCAutoRefCount)
+ if (Self.getLangOpts().ObjCAutoRefCount || Self.getLangOpts().ObjCWeak)
checkObjCConversion(Sema::CCK_OtherCast);
} else if (Kind == CK_BitCast) {
checkCastAlign();
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits