From: Fariborz Jahanian Date: Thu, 10 Jan 2008 20:33:58 +0000 (+0000) Subject: Recover from user typo not having proper @interface decl and a bad foreach decl. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=20552d2842245692b649e0d25380670922f954a2;p=clang Recover from user typo not having proper @interface decl and a bad foreach decl. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@45839 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/Sema/SemaDeclObjC.cpp b/Sema/SemaDeclObjC.cpp index 89b7611d86..b2e7b79556 100644 --- a/Sema/SemaDeclObjC.cpp +++ b/Sema/SemaDeclObjC.cpp @@ -43,9 +43,14 @@ void Sema::ObjCActOnStartOfMethodDef(Scope *FnBodyScope, DeclTy *D) { PI.IdentLoc = SourceLocation(); // synthesized vars have a null location. PI.InvalidType = false; if (MDecl->isInstance()) { - QualType selfTy = Context.getObjCInterfaceType(MDecl->getClassInterface()); - selfTy = Context.getPointerType(selfTy); - PI.TypeInfo = selfTy.getAsOpaquePtr(); + ObjCInterfaceDecl *OID = MDecl->getClassInterface(); + // There may be no interface context due to error in declaration of the + // interface (which has been reported). Recover gracefully + if (OID) { + QualType selfTy = Context.getObjCInterfaceType(OID); + selfTy = Context.getPointerType(selfTy); + PI.TypeInfo = selfTy.getAsOpaquePtr(); + } } else PI.TypeInfo = Context.getObjCIdType().getAsOpaquePtr(); CurMethodDecl->setSelfDecl(ActOnParamDeclarator(PI, FnBodyScope)); diff --git a/Sema/SemaStmt.cpp b/Sema/SemaStmt.cpp index fbe9294b20..4cad4a9f66 100644 --- a/Sema/SemaStmt.cpp +++ b/Sema/SemaStmt.cpp @@ -538,23 +538,25 @@ Sema::ActOnObjCForCollectionStmt(SourceLocation ForLoc, Stmt *First = static_cast(first); Expr *Second = static_cast(second); Stmt *Body = static_cast(body); - QualType FirstType; - if (DeclStmt *DS = dyn_cast_or_null(First)) { - FirstType = cast(DS->getDecl())->getType(); - // C99 6.8.5p3: The declaration part of a 'for' statement shall only declare - // identifiers for objects having storage class 'auto' or 'register'. - ScopedDecl *D = DS->getDecl(); - BlockVarDecl *BVD = cast(D); - if (!BVD->hasLocalStorage()) - return Diag(BVD->getLocation(), diag::err_non_variable_decl_in_for); - if (D->getNextDeclarator()) - return Diag(D->getLocation(), diag::err_toomany_element_decls); + if (First) { + QualType FirstType; + if (DeclStmt *DS = dyn_cast(First)) { + FirstType = cast(DS->getDecl())->getType(); + // C99 6.8.5p3: The declaration part of a 'for' statement shall only declare + // identifiers for objects having storage class 'auto' or 'register'. + ScopedDecl *D = DS->getDecl(); + BlockVarDecl *BVD = cast(D); + if (!BVD->hasLocalStorage()) + return Diag(BVD->getLocation(), diag::err_non_variable_decl_in_for); + if (D->getNextDeclarator()) + return Diag(D->getLocation(), diag::err_toomany_element_decls); + } + else + FirstType = static_cast(first)->getType(); + if (!isObjCObjectPointerType(FirstType)) + Diag(ForLoc, diag::err_selector_element_type, + FirstType.getAsString(), First->getSourceRange()); } - else - FirstType = static_cast(first)->getType(); - if (!isObjCObjectPointerType(FirstType)) - Diag(ForLoc, diag::err_selector_element_type, - FirstType.getAsString(), First->getSourceRange()); if (Second) { DefaultFunctionArrayConversion(Second); QualType SecondType = Second->getType(); diff --git a/test/Parser/objc-foreach-error-1.m b/test/Parser/objc-foreach-error-1.m new file mode 100644 index 0000000000..693f12e2ff --- /dev/null +++ b/test/Parser/objc-foreach-error-1.m @@ -0,0 +1,25 @@ +// RUN: clang -fsyntax-only -verify %s + +ce MyList // expected-error {{expected '=', ',', ';', 'asm', or '__attribute__' after declarator}} +@end + + +@implementation MyList +- (unsigned int)countByEnumeratingWithState: (struct __objcFastEnumerationState *)state objects: (id *)items count:(unsigned int)stackcount +{ + return 0; +} +@end + + +int LOOP(); + +@implementation MyList (BasicTest) // expected-error {{cannot find interface declaration for 'MyList'}} +- (void)compilerTestAgainst { +MyList * el; // expected-error {{use of undeclared identifier 'MyList'}} + for (el in @"foo") // expected-error {{use of undeclared identifier 'el'}} \ + // expected-error {{cannot find interface declaration for 'NSConstantString'}} + { LOOP(); } +} +@end +