diff options
author | Steve Naroff <snaroff@apple.com> | 2008-06-04 23:08:38 +0000 |
---|---|---|
committer | Steve Naroff <snaroff@apple.com> | 2008-06-04 23:08:38 +0000 |
commit | cb28be6e82809f9f514585ac2692fa04bb56978a (patch) | |
tree | 211648bc41fe66eaba1449d59c4fab775eaea05b | |
parent | 44a3dded8080c5c9cfdad208ade8f8f7850d9a4f (diff) |
Fix crash identified by <rdar://problem/5986085>.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@51969 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Sema/SemaExprObjC.cpp | 34 | ||||
-rw-r--r-- | test/Sema/objc-typedef-class.m | 79 |
2 files changed, 102 insertions, 11 deletions
diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp index d833efe309..e2e23ce063 100644 --- a/lib/Sema/SemaExprObjC.cpp +++ b/lib/Sema/SemaExprObjC.cpp @@ -166,19 +166,31 @@ Sema::ExprResult Sema::ActOnClassMessage( } else ClassDecl = getObjCInterfaceDecl(receiverName); - // FIXME: can ClassDecl ever be null? - ObjCMethodDecl *Method = ClassDecl->lookupClassMethod(Sel); + // ClassDecl is null in the following case. + // + // typedef XCElementDisplayRect XCElementGraphicsRect; + // + // @implementation XCRASlice + // - whatever { // Note that XCElementGraphicsRect is a typedef name. + // _sGraphicsDelegate =[[XCElementGraphicsRect alloc] init]; + // } + // + // FIXME: Investigate why GCC allows the above. + ObjCMethodDecl *Method = 0; QualType returnType; - - // If we have an implementation in scope, check "private" methods. - if (!Method) { - if (ObjCImplementationDecl *ImpDecl = - ObjCImplementations[ClassDecl->getIdentifier()]) - Method = ImpDecl->getClassMethod(Sel); + if (ClassDecl) { + Method = ClassDecl->lookupClassMethod(Sel); + + // If we have an implementation in scope, check "private" methods. + if (!Method) { + if (ObjCImplementationDecl *ImpDecl = + ObjCImplementations[ClassDecl->getIdentifier()]) + Method = ImpDecl->getClassMethod(Sel); + } + // Before we give up, check if the selector is an instance method. + if (!Method) + Method = ClassDecl->lookupInstanceMethod(Sel); } - // Before we give up, check if the selector is an instance method. - if (!Method) - Method = ClassDecl->lookupInstanceMethod(Sel); if (!Method) { Diag(lbrac, diag::warn_method_not_found, std::string("+"), Sel.getName(), SourceRange(lbrac, rbrac)); diff --git a/test/Sema/objc-typedef-class.m b/test/Sema/objc-typedef-class.m new file mode 100644 index 0000000000..a35408ba97 --- /dev/null +++ b/test/Sema/objc-typedef-class.m @@ -0,0 +1,79 @@ +// RUN: clang -fsyntax-only -verify %s +typedef signed char BOOL; +typedef unsigned int NSUInteger; +typedef struct _NSZone NSZone; + +@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator; + +@protocol NSObject - (BOOL) isEqual:(id) object; @end +@protocol NSCopying - (id) copyWithZone:(NSZone *) zone; @end +@protocol NSCoding - (void) encodeWithCoder:(NSCoder *) aCoder; @end + +@interface NSObject < NSObject > {} ++(id) alloc; +@end + +typedef float CGFloat; + +@interface NSTask:NSObject +- (id) init; +@end + +typedef NSUInteger NSControlSize; +typedef struct __CFlags {} _CFlags; + +@interface NSCell:NSObject < NSCopying, NSCoding > {} +@end + +@interface NSActionCell:NSCell {} @end + +@class NSAttributedString, NSFont, NSImage, NSSound; + +typedef struct _XCElementInset {} XCElementInset; + +@protocol XCElementP < NSObject > +-(BOOL) vertical; +@end + +@protocol XCElementDisplayDelegateP; +@protocol XCElementDisplayDelegateP < NSObject > +-(void) configureForControlSize:(NSControlSize)size font:(NSFont *)font addDefaultSpace:(XCElementInset) additionalSpace; +@end + +@protocol XCElementSpacerP < XCElementP > +@end + +typedef NSObject < XCElementSpacerP > XCElementSpacer; + +@protocol XCElementTogglerP < XCElementP > -(void) setDisplayed:(BOOL) displayed; +@end + +// FIXME: investigate this redefinition error - gcc apparently accepts it. +typedef NSObject < XCElementTogglerP > XCElementToggler; // expected-error{{previous definition is here}} + +@interface XCElementRootFace:NSObject {} @end + +@interface XCElementFace:XCElementRootFace {} @end + +@class XCElementToggler; // expected-error{{redefinition of 'XCElementToggler' as different kind of symbol}} + +@interface XCRASlice:XCElementFace {} @end + +@class XCElementSpacings; + +@interface XCElementDisplay:NSObject < XCElementDisplayDelegateP > {} @end +@interface XCElementDisplayRect:XCElementDisplay {} @end + +typedef XCElementDisplayRect XCElementGraphicsRect; + +@interface XCElementDisplayFillerImage:XCElementDisplay {} @end + +@implementation XCRASlice +- (void) addSliceWithLabel:(NSString *)label statusKey:(NSString *)statusKey disclosed:(BOOL)disclosed +{ + static XCElementGraphicsRect *_sGraphicsDelegate = ((void *) 0); + if (!_sGraphicsDelegate) { + _sGraphicsDelegate =[[XCElementGraphicsRect alloc] init]; // expected-warning{{method '+alloc' not found (return type defaults to 'id')}} + } +} +@end |