forked from OSchip/llvm-project
Fixes an instance method meta-data generation bug in
ObjC NeXt runtime where method pointer registered in metadata belongs to an unrelated method. Ast part of this fix, I turned at @end missing warning (for class implementations) into an error as we can never be sure that meta-data being generated is correct. // rdar://9072317 llvm-svn: 130019
This commit is contained in:
parent
6d277517d1
commit
c057794adb
|
@ -286,7 +286,7 @@ def err_missing_id_definition : Error<"cannot find definition of 'id'">;
|
|||
def err_missing_proto_definition : Error<
|
||||
"cannot find definition of 'Protocol'">;
|
||||
def err_missing_class_definition : Error<"cannot find definition of 'Class'">;
|
||||
def warn_expected_implementation : Warning<
|
||||
def err_expected_implementation : Error<
|
||||
"@end must appear in an @implementation context">;
|
||||
def error_property_ivar_decl : Error<
|
||||
"property synthesize requires specification of an ivar">;
|
||||
|
|
|
@ -393,7 +393,7 @@ def note_declared_at : Note<"declared here">;
|
|||
def note_method_declared_at : Note<"method declared here">;
|
||||
def err_setter_type_void : Error<"type of setter must be void">;
|
||||
def err_duplicate_method_decl : Error<"duplicate declaration of method %0">;
|
||||
def warn_missing_atend : Warning<"'@end' is missing in implementation context">;
|
||||
def err_missing_atend : Error<"'@end' is missing in implementation context">;
|
||||
def err_objc_var_decl_inclass :
|
||||
Error<"cannot declare variable inside @interface or @protocol">;
|
||||
def error_missing_method_context : Error<
|
||||
|
|
|
@ -2069,6 +2069,8 @@ void CGObjCMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
|
|||
4, true);
|
||||
DefinedCategories.push_back(GV);
|
||||
DefinedCategoryNames.insert(ExtName.str());
|
||||
// method definition entries must be clear for next implementation.
|
||||
MethodDefinitions.clear();
|
||||
}
|
||||
|
||||
// FIXME: Get from somewhere?
|
||||
|
@ -2196,6 +2198,8 @@ void CGObjCMac::GenerateClass(const ObjCImplementationDecl *ID) {
|
|||
else
|
||||
GV = CreateMetadataVar(Name, Init, Section, 4, true);
|
||||
DefinedClasses.push_back(GV);
|
||||
// method definition entries must be clear for next implementation.
|
||||
MethodDefinitions.clear();
|
||||
}
|
||||
|
||||
llvm::Constant *CGObjCMac::EmitMetaClass(const ObjCImplementationDecl *ID,
|
||||
|
@ -4978,6 +4982,8 @@ void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) {
|
|||
// Force the definition of the EHType if necessary.
|
||||
if (flags & CLS_EXCEPTION)
|
||||
GetInterfaceEHType(ID->getClassInterface(), true);
|
||||
// Make sure method definition entries are all clear for next implementation.
|
||||
MethodDefinitions.clear();
|
||||
}
|
||||
|
||||
/// GenerateProtocolRef - This routine is called to generate code for
|
||||
|
@ -5106,6 +5112,8 @@ void CGObjCNonFragileABIMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
|
|||
// Determine if this category is also "non-lazy".
|
||||
if (ImplementationIsNonLazy(OCD))
|
||||
DefinedNonLazyCategories.push_back(GCATV);
|
||||
// method definition entries must be clear for next implementation.
|
||||
MethodDefinitions.clear();
|
||||
}
|
||||
|
||||
/// GetMethodConstant - Return a struct objc_method constant for the
|
||||
|
|
|
@ -1387,7 +1387,7 @@ Decl *Parser::ParseObjCAtEndDeclaration(SourceRange atEnd) {
|
|||
}
|
||||
else {
|
||||
// missing @implementation
|
||||
Diag(atEnd.getBegin(), diag::warn_expected_implementation);
|
||||
Diag(atEnd.getBegin(), diag::err_expected_implementation);
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
|
|
@ -1536,7 +1536,7 @@ void Sema::ActOnAtEnd(Scope *S, SourceRange AtEnd,
|
|||
SourceLocation L = ClassDecl->getLocation();
|
||||
AtEnd.setBegin(L);
|
||||
AtEnd.setEnd(L);
|
||||
Diag(L, diag::warn_missing_atend);
|
||||
Diag(L, diag::err_missing_atend);
|
||||
}
|
||||
|
||||
// FIXME: Remove these and use the ObjCContainerDecl/DeclContext.
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -S -o %t %s
|
||||
// RUN: FileCheck < %t %s
|
||||
|
||||
// rdar://9072317
|
||||
|
||||
/** The problem looks like clang getting confused when a single translation unit
|
||||
contains a protocol with a property and two classes that implement that protocol
|
||||
and synthesize the property.
|
||||
*/
|
||||
|
||||
@protocol Proto
|
||||
@property (assign) id prop;
|
||||
@end
|
||||
|
||||
@interface NSObject @end
|
||||
|
||||
@interface Foo : NSObject <Proto> { int x; } @end
|
||||
|
||||
@interface Bar : NSObject <Proto> @end
|
||||
|
||||
@implementation Foo
|
||||
@synthesize prop;
|
||||
@end
|
||||
|
||||
@implementation Bar
|
||||
@synthesize prop;
|
||||
@end
|
||||
|
||||
// CHECK: l_OBJC_$_INSTANCE_METHODS_Bar:
|
||||
// CHECK-NEXT .long 24
|
||||
// CHECK-NEXT .long 2
|
||||
// CHECK-NEXT .quad L_OBJC_METH_VAR_NAME_
|
||||
// CHECK-NEXT .quad L_OBJC_METH_VAR_TYPE_
|
||||
// CHECK-NEXT .quad "-[Bar prop]"
|
|
@ -1,24 +0,0 @@
|
|||
// RUN: %clang_cc1 -triple i386-apple-darwin9 -emit-llvm %s -o - | FileCheck %s
|
||||
|
||||
@interface I0
|
||||
@end
|
||||
|
||||
@implementation I0 // expected-warning {{'@end' is missing in implementation context}}
|
||||
- meth { return 0; }
|
||||
|
||||
@interface I1 : I0
|
||||
@end
|
||||
|
||||
@implementation I1 // expected-warning {{'@end' is missing in implementation context}}
|
||||
-(void) im0 { self = [super init]; }
|
||||
|
||||
@interface I2 : I0
|
||||
- I2meth;
|
||||
@end
|
||||
|
||||
@implementation I2 // expected-warning {{'@end' is missing in implementation context}}
|
||||
- I2meth { return 0; }
|
||||
|
||||
@implementation I2(CAT) // expected-warning {{'@end' is missing in implementation context}}
|
||||
|
||||
// CHECK: @"\01L_OBJC_CLASS_I1" = internal global
|
|
@ -5,4 +5,4 @@
|
|||
extern "C" { @implementation Foo - (id)initWithBar:(Baz<WozBar>)pepper {
|
||||
|
||||
// CHECK: warning: cannot find interface declaration for 'Foo'
|
||||
// CHECK: warning: '@end' is missing in implementation context
|
||||
// CHECK: error: '@end' is missing in implementation context
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
// RUN: %clang_cc1 -fsyntax-only -verify %s
|
||||
@end // expected-warning {{@end must appear in an @implementation context}}
|
||||
@end // expected-error {{@end must appear in an @implementation context}}
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
// RUN: %clang_cc1 -triple i386-apple-darwin9 -fsyntax-only -verify %s
|
||||
|
||||
@interface I0
|
||||
@end
|
||||
|
||||
@implementation I0 // expected-error {{'@end' is missing in implementation context}}
|
||||
- meth { return 0; }
|
||||
|
||||
@interface I1 : I0
|
||||
@end
|
||||
|
||||
@implementation I1 // expected-error {{'@end' is missing in implementation context}}
|
||||
-(void) im0 { self = [super init]; } // expected-warning {{nstance method '-init' not found }}
|
||||
|
||||
@interface I2 : I0
|
||||
- I2meth;
|
||||
@end
|
||||
|
||||
@implementation I2 // expected-error {{'@end' is missing in implementation context}}
|
||||
- I2meth { return 0; }
|
||||
|
||||
@implementation I2(CAT) // expected-error {{'@end' is missing in implementation context}}
|
Loading…
Reference in New Issue