aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td5
-rw-r--r--lib/Sema/SemaDecl.cpp62
-rw-r--r--test/ARCMT/checking.m2
-rw-r--r--test/SemaObjC/arc-decls.m8
4 files changed, 38 insertions, 39 deletions
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index 54b8c6f64c..4e48089e38 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3696,8 +3696,9 @@ def err_arc_mismatched_cast : Error<
" to %3 is disallowed with ARC">;
def err_arc_nolifetime_behavior : Error<
"explicit ownership qualifier on cast result has no effect">;
-def err_arc_objc_object_in_struct : Error<
- "ARC forbids %select{Objective-C objects|blocks}0 in structs or unions">;
+def err_arc_objc_object_in_tag : Error<
+ "ARC forbids %select{Objective-C objects|blocks}0 of type %1 in "
+ "%select{struct|interface|union|<<ERROR>>|enum}2">;
def err_arc_objc_property_default_assign_on_object : Error<
"ARC forbids synthesizing a property of an Objective-C object "
"with unspecified ownership or storage attribute">;
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index a5f39a82f1..aa4a865344 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -10498,44 +10498,42 @@ void Sema::ActOnFields(Scope* S,
<< FixItHint::CreateInsertion(FD->getLocation(), "*");
QualType T = Context.getObjCObjectPointerType(FD->getType());
FD->setType(T);
- } else if (!getLangOpts().CPlusPlus) {
- if (getLangOpts().ObjCAutoRefCount && Record && !ARCErrReported) {
- // It's an error in ARC 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) {
- SourceLocation loc = FD->getLocation();
- if (getSourceManager().isInSystemHeader(loc)) {
- if (!FD->hasAttr<UnavailableAttr>()) {
- FD->addAttr(new (Context) UnavailableAttr(loc, Context,
- "this system field has retaining ownership"));
- }
- } else {
- Diag(FD->getLocation(), diag::err_arc_objc_object_in_struct)
- << T->isBlockPointerType();
+ } else if (getLangOpts().ObjCAutoRefCount && Record && !ARCErrReported &&
+ (!getLangOpts().CPlusPlus || Record->isUnion())) {
+ // It's an error in ARC 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) {
+ SourceLocation loc = FD->getLocation();
+ if (getSourceManager().isInSystemHeader(loc)) {
+ if (!FD->hasAttr<UnavailableAttr>()) {
+ FD->addAttr(new (Context) UnavailableAttr(loc, Context,
+ "this system field has retaining ownership"));
}
- ARCErrReported = true;
+ } else {
+ Diag(FD->getLocation(), diag::err_arc_objc_object_in_tag)
+ << T->isBlockPointerType() << T << Record->getTagKind();
}
+ ARCErrReported = true;
}
- else if (getLangOpts().ObjC1 &&
+ } else if (getLangOpts().ObjC1 &&
getLangOpts().getGC() != LangOptions::NonGC &&
Record && !Record->hasObjectMember()) {
- if (FD->getType()->isObjCObjectPointerType() ||
- FD->getType().isObjCGCStrong())
+ if (FD->getType()->isObjCObjectPointerType() ||
+ FD->getType().isObjCGCStrong())
+ Record->setHasObjectMember(true);
+ else if (Context.getAsArrayType(FD->getType())) {
+ QualType BaseType = Context.getBaseElementType(FD->getType());
+ if (BaseType->isRecordType() &&
+ BaseType->getAs<RecordType>()->getDecl()->hasObjectMember())
Record->setHasObjectMember(true);
- else if (Context.getAsArrayType(FD->getType())) {
- QualType BaseType = Context.getBaseElementType(FD->getType());
- if (BaseType->isRecordType() &&
- BaseType->getAs<RecordType>()->getDecl()->hasObjectMember())
- Record->setHasObjectMember(true);
- else if (BaseType->isObjCObjectPointerType() ||
- BaseType.isObjCGCStrong())
- Record->setHasObjectMember(true);
- }
+ else if (BaseType->isObjCObjectPointerType() ||
+ BaseType.isObjCGCStrong())
+ Record->setHasObjectMember(true);
}
}
if (Record && FD->getType().isVolatileQualified())
diff --git a/test/ARCMT/checking.m b/test/ARCMT/checking.m
index 9fd50029d0..a5c364a058 100644
--- a/test/ARCMT/checking.m
+++ b/test/ARCMT/checking.m
@@ -117,7 +117,7 @@ void test1(A *a, BOOL b, struct UnsafeS *unsafeS) {
}
struct S {
- A* a; // expected-error {{ARC forbids Objective-C objects in structs or unions}}
+ A* a; // expected-error {{ARC forbids Objective-C objects of type 'A *__strong' in struct}}
};
@interface B
diff --git a/test/SemaObjC/arc-decls.m b/test/SemaObjC/arc-decls.m
index a53b52acd8..e9ce415188 100644
--- a/test/SemaObjC/arc-decls.m
+++ b/test/SemaObjC/arc-decls.m
@@ -3,17 +3,17 @@
// rdar://8843524
struct A {
- id x; // expected-error {{ARC forbids Objective-C objects in structs or unions}}
+ id x; // expected-error {{ARC forbids Objective-C objects of type '__strong id' in struct}}
};
union u {
- id u; // expected-error {{ARC forbids Objective-C objects in structs or unions}}
+ id u; // expected-error {{ARC forbids Objective-C objects of type '__strong id' in union}}
};
@interface I {
struct A a;
struct B {
- id y[10][20]; // expected-error {{ARC forbids Objective-C objects in structs or unions}}
+ id y[10][20]; // expected-error {{ARC forbids Objective-C objects}}
id z;
} b;
@@ -23,7 +23,7 @@ union u {
// rdar://10260525
struct r10260525 {
- id (^block) (); // expected-error {{ARC forbids blocks in structs or unions}}
+ id (^block) (); // expected-error {{ARC forbids blocks of type 'id (^__strong)()' in struct}}
};
struct S {