forked from OSchip/llvm-project
Forbid the use of objects in unions in Objective-C++ ARC. Fixes
<rdar://problem/13098104>. llvm-svn: 173708
This commit is contained in:
parent
137f1b991e
commit
e6c3fa0b27
|
@ -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">;
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in New Issue