From: Fariborz Jahanian Date: Tue, 6 Apr 2010 22:43:48 +0000 (+0000) Subject: Patch to not build ivar ASTs when they are ilegally X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=0bd04596e4645ff145a046dfb3475f39674060d9;p=clang Patch to not build ivar ASTs when they are ilegally declared in categories. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@100577 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Parse/ParseObjc.cpp b/lib/Parse/ParseObjc.cpp index 243be0ed45..123a96261a 100644 --- a/lib/Parse/ParseObjc.cpp +++ b/lib/Parse/ParseObjc.cpp @@ -1053,7 +1053,8 @@ void Parser::ParseObjCClassInstanceVariables(DeclPtrTy interfaceDecl, = P.Actions.ActOnIvar(P.CurScope, FD.D.getDeclSpec().getSourceRange().getBegin(), IDecl, FD.D, FD.BitfieldSize, visibility); - AllIvarDecls.push_back(Field); + if (Field) + AllIvarDecls.push_back(Field); return Field; } } Callback(*this, interfaceDecl, visibility, AllIvarDecls); diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 541c27169a..3556057173 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -5747,8 +5747,16 @@ Sema::DeclPtrTy Sema::ActOnIvar(Scope *S, // Case of ivar declared in an implementation. Context is that of its class. EnclosingContext = IMPDecl->getClassInterface(); assert(EnclosingContext && "Implementation has no class interface!"); - } else + } else { + if (ObjCCategoryDecl *CDecl = + dyn_cast(EnclosingDecl)) { + if (!LangOpts.ObjCNonFragileABI2 || !CDecl->IsClassExtension()) { + Diag(Loc, diag::err_misplaced_ivar) << CDecl->IsClassExtension(); + return DeclPtrTy(); + } + } EnclosingContext = EnclosingDecl; + } // Construct the decl. ObjCIvarDecl *NewID = ObjCIvarDecl::Create(Context, @@ -5926,16 +5934,14 @@ void Sema::ActOnFields(Scope* S, CheckImplementationIvars(IMPDecl, ClsFields, RecFields.size(), RBrac); } else if (ObjCCategoryDecl *CDecl = dyn_cast(EnclosingDecl)) { - if (!LangOpts.ObjCNonFragileABI2 || !CDecl->IsClassExtension()) - Diag(LBrac, diag::err_misplaced_ivar) << CDecl->IsClassExtension(); - else { - // FIXME. Class extension does not have a LocEnd field. - // CDecl->setLocEnd(RBrac); - // Add ivar's to class extension's DeclContext. - for (unsigned i = 0, e = RecFields.size(); i != e; ++i) { - ClsFields[i]->setLexicalDeclContext(CDecl); - CDecl->addDecl(ClsFields[i]); - } + // case of ivars in class extension; all other cases have been + // reported as errors elsewhere. + // FIXME. Class extension does not have a LocEnd field. + // CDecl->setLocEnd(RBrac); + // Add ivar's to class extension's DeclContext. + for (unsigned i = 0, e = RecFields.size(); i != e; ++i) { + ClsFields[i]->setLexicalDeclContext(CDecl); + CDecl->addDecl(ClsFields[i]); } } } diff --git a/test/SemaObjC/ivar-in-class-extension-error.m b/test/SemaObjC/ivar-in-class-extension-error.m index ffc0e8b839..6e0b577976 100644 --- a/test/SemaObjC/ivar-in-class-extension-error.m +++ b/test/SemaObjC/ivar-in-class-extension-error.m @@ -3,13 +3,13 @@ @interface A @end -@interface A () { // expected-error {{ivars may not be placed in class extension}} - int _p0; +@interface A () { + int _p0; // expected-error {{ivars may not be placed in class extension}} } @property int p0; @end -@interface A(CAT) { // expected-error {{ivars may not be placed in categories}} - int _p1; +@interface A(CAT) { + int _p1; // expected-error {{ivars may not be placed in categories}} } @end diff --git a/test/SemaObjC/ivar-in-class-extension.m b/test/SemaObjC/ivar-in-class-extension.m index e1a649cd47..4130d8f962 100644 --- a/test/SemaObjC/ivar-in-class-extension.m +++ b/test/SemaObjC/ivar-in-class-extension.m @@ -31,12 +31,12 @@ int fn3(SomeClass *obj) { @end @interface SomeClass (Category) - { // expected-error {{ivars may not be placed in categories}} - int categoryIvar; + { + int categoryIvar; // expected-error {{ivars may not be placed in categories}} } @end @interface SomeClass (Category1) - { // expected-error {{ivars may not be placed in categories}} + { } @end