diff options
author | Douglas Gregor <dgregor@apple.com> | 2013-01-28 19:08:09 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2013-01-28 19:08:09 +0000 |
commit | 4581d45405f07374770366be8644d52733985833 (patch) | |
tree | 7029a4d003b59a528ae17d641e5c2bac22a2ba60 /lib/Sema/SemaDecl.cpp | |
parent | 20c6f2eae500242d3aef5daaa55d440a0786a1fd (diff) |
Forbid the use of objects in unions in Objective-C++ ARC. Fixes
<rdar://problem/13098104>.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@173708 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaDecl.cpp')
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 62 |
1 files changed, 30 insertions, 32 deletions
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()) |