diff options
Diffstat (limited to 'gcc/testsuite/objc.dg')
44 files changed, 1448 insertions, 22 deletions
diff --git a/gcc/testsuite/objc.dg/comp-types-8.m b/gcc/testsuite/objc.dg/comp-types-8.m new file mode 100644 index 00000000000..7b940a7ba97 --- /dev/null +++ b/gcc/testsuite/objc.dg/comp-types-8.m @@ -0,0 +1,25 @@ +/* APPLE LOCAL file Objective-C */ +/* { dg-do compile } */ +/* Another gimplifier ICE... */ + +#include <objc/Object.h> + +@interface MyView: Object { + int _frame; +} +- (void)_finalize; +@end + +@interface MyViewTemplate: MyView { + void *_className; +} +- (id)createRealObject; +@end + +@implementation MyViewTemplate +- (id)createRealObject { + id realObj; + *(MyView *)realObj = *(MyView *)self; + return realObj; +} +@end diff --git a/gcc/testsuite/objc.dg/const-cfstring-1.m b/gcc/testsuite/objc.dg/const-cfstring-1.m new file mode 100644 index 00000000000..8645022b6ef --- /dev/null +++ b/gcc/testsuite/objc.dg/const-cfstring-1.m @@ -0,0 +1,57 @@ +/* APPLE LOCAL file constant cfstrings */ +/* Test the -fconstant-cfstrings option for constructing + compile-time immutable CFStrings, and their interoperation + with both Cocoa and CoreFoundation. This will only work + on MacOS X 10.1.2 and later. */ +/* Developed by Ziemowit Laski <zlaski@apple.com>. */ + +/* { dg-do run { target *-*-darwin* } } */ +/* { dg-options "-fconstant-cfstrings -framework Cocoa" } */ + +#import <Foundation/NSString.h> +#import <CoreFoundation/CFString.h> +#include <stdlib.h> + +void printOut(NSString *str) { + NSLog(@"The value of str is: %@", str); +} + +CFStringRef s0a = CFSTR("Compile-time string literal"); +CFStringRef s0b = CFSTR("Compile-time string literal"); + +void checkNSRange(NSRange r) { + if (r.location != 6 || r.length != 5) { + printOut(@"Range check failed"); + abort(); + } +} + +void checkCFRange(CFRange r) { + if (r.location != 6 || r.length != 5) { + printOut(@"Range check failed"); + abort(); + } +} + +int main(void) { + const NSString *s1 = @"Compile-time string literal"; + CFStringRef s2 = CFSTR("Compile-time string literal"); + + checkNSRange([@"Hello World" rangeOfString:@"World"]); + checkNSRange([(id)CFSTR("Hello World") rangeOfString:@"World"]); + checkNSRange([@"Hello World" rangeOfString:(id)CFSTR("World")]); + checkNSRange([(id)CFSTR("Hello World") rangeOfString:(id)CFSTR("World")]); + + checkCFRange(CFStringFind((CFStringRef)@"Hello World", (CFStringRef)@"World", 0)); + checkCFRange(CFStringFind(CFSTR("Hello World"), (CFStringRef)@"World", 0)); + checkCFRange(CFStringFind((CFStringRef)@"Hello World", CFSTR("World"), 0)); + checkCFRange(CFStringFind(CFSTR("Hello World"), CFSTR("World"), 0)); + + /* Check for string uniquing. */ + if (s0a != s0b || s0a != s2 || s1 != (id)s2) { + NSLog(@"String uniquing failed"); + abort (); + } + + return 0; +} diff --git a/gcc/testsuite/objc.dg/const-cfstring-2.m b/gcc/testsuite/objc.dg/const-cfstring-2.m new file mode 100644 index 00000000000..57b8d95a7d4 --- /dev/null +++ b/gcc/testsuite/objc.dg/const-cfstring-2.m @@ -0,0 +1,26 @@ +/* APPLE LOCAL file constant CFStrings */ +/* Test the -Wnonportable-cfstrings option, which should give + warnings if non-ASCII characters are embedded in constant + CFStrings. This will only work on MacOS X 10.2 and later. */ +/* Developed by Ziemowit Laski <zlaski@apple.com>. */ + +/* { dg-do compile { target *-*-darwin* } } */ +/* { dg-options "-fconstant-cfstrings -Wnonportable-cfstrings" } */ + +#import <Foundation/NSString.h> +#import <CoreFoundation/CFString.h> + +#ifndef __CONSTANT_CFSTRINGS__ +#error The -fconstant-cfstrings option is not functioning properly +#endif + +void foo(void) { + NSString *s1 = @"Compile-time string literal"; + CFStringRef s2 = CFSTR("Compile-time string literal"); + NSString *s3 = @"Non-ASCII literal - \222"; /* { dg-warning "non-ASCII character in CFString literal" } */ + CFStringRef s4 = CFSTR("\222 - Non-ASCII literal"); /* { dg-warning "non-ASCII character in CFString literal" } */ + CFStringRef s5 = CFSTR("Non-ASCII (\222) literal"); /* { dg-warning "non-ASCII character in CFString literal" } */ + NSString *s6 = @"\0Embedded NUL"; /* { dg-warning "embedded NUL in CFString literal" } */ + CFStringRef s7 = CFSTR("Embedded \0NUL"); /* { dg-warning "embedded NUL in CFString literal" } */ + CFStringRef s8 = CFSTR("Embedded NUL\0"); /* { dg-warning "embedded NUL in CFString literal" } */ +} diff --git a/gcc/testsuite/objc.dg/const-cfstring-3.m b/gcc/testsuite/objc.dg/const-cfstring-3.m new file mode 100644 index 00000000000..82f361cec6f --- /dev/null +++ b/gcc/testsuite/objc.dg/const-cfstring-3.m @@ -0,0 +1,26 @@ +/* APPLE LOCAL file constant strings */ +/* Test for assigning compile-time constant-string objects to static variables. */ +/* Contributed by Ziemowit Laski <zlaski@apple.com> */ + +/* { dg-options "-fconstant-cfstrings -framework Foundation" } */ +/* { dg-do run { target *-*-darwin* } } */ + +#include <stdlib.h> + +typedef const struct __CFString * CFStringRef; +static CFStringRef appKey = (CFStringRef) @"com.apple.soundpref"; + +static int CFPreferencesSynchronize (CFStringRef ref) { + return ref == appKey; +} + +static void PrefsSynchronize() +{ + if(!CFPreferencesSynchronize(appKey)) + abort(); +} + +int main(void) { + PrefsSynchronize(); + return 0; +} diff --git a/gcc/testsuite/objc.dg/const-cfstring-4.m b/gcc/testsuite/objc.dg/const-cfstring-4.m new file mode 100644 index 00000000000..9078bfa2313 --- /dev/null +++ b/gcc/testsuite/objc.dg/const-cfstring-4.m @@ -0,0 +1,12 @@ +/* APPLE LOCAL file constant strings */ +/* Test if constant CFStrings get placed in the correct section. */ +/* Contributed by Ziemowit Laski <zlaski@apple.com> */ + +/* { dg-options "-fconstant-cfstrings" } */ +/* { dg-do compile { target *-*-darwin* } } */ + +typedef const struct __CFString * CFStringRef; +static CFStringRef appKey = (CFStringRef) @"com.apple.soundpref"; + +/* { dg-final { scan-assembler ".section __DATA, __cfstring" } } */ +/* { dg-final { scan-assembler ".long\t___CFConstantStringClassReference\n\t.long\t1992\n\t.long\t.*\n\t.long\t19\n\t.data" } } */ diff --git a/gcc/testsuite/objc.dg/dg.exp b/gcc/testsuite/objc.dg/dg.exp index ebf952967c7..7b3eba41d98 100644 --- a/gcc/testsuite/objc.dg/dg.exp +++ b/gcc/testsuite/objc.dg/dg.exp @@ -28,7 +28,8 @@ if ![info exists DEFAULT_CFLAGS] then { dg-init # Main loop. -dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[m\]]] \ +# APPLE LOCAL -ObjC +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[mc\]]] \ "" $DEFAULT_CFLAGS # All done. diff --git a/gcc/testsuite/objc.dg/encode-1.m b/gcc/testsuite/objc.dg/encode-1.m index 868c3254753..126e5d010f4 100644 --- a/gcc/testsuite/objc.dg/encode-1.m +++ b/gcc/testsuite/objc.dg/encode-1.m @@ -1,9 +1,9 @@ +/* APPLE LOCAL file bool encoding */ /* Test if the Objective-C @encode machinery distinguishes between - 'BOOL *' (which should be encoded as a pointer to BOOL) and 'char *' (which - should be encoded as '*'). This is somewhat tricky wrt the NeXT runtime, - where we have 'typedef char BOOL'. */ + 'BOOL *' (which should be encoded as '^c') and 'char *' (which + should be encoded as '*'). */ /* Contributed by Ziemowit Laski <zlaski@apple.com>. */ -/* { dg-options "-fnext-runtime -lobjc" } */ +/* { dg-options "-lobjc" } */ /* { dg-do run } */ #include <string.h> @@ -12,10 +12,9 @@ int main(void) { const char *BOOL_ptr = @encode(BOOL *); - const char *BOOL_ = @encode(BOOL); const char *char_ptr = @encode(char *); - - if(*BOOL_ptr != '^' || strcmp(BOOL_ptr + 1, BOOL_)) + + if(strcmp(BOOL_ptr, "^c")) abort(); if(strcmp(char_ptr, "*")) diff --git a/gcc/testsuite/objc.dg/encode-6.m b/gcc/testsuite/objc.dg/encode-6.m new file mode 100644 index 00000000000..d23dc6cf399 --- /dev/null +++ b/gcc/testsuite/objc.dg/encode-6.m @@ -0,0 +1,23 @@ +/* APPLE LOCAL file Objective-C++ */ +/* Test for graceful encoding of const-qualified fields and parameters. */ +/* Author: Ziemowit Laski <zlaski@apple.com> */ +/* { dg-do compile } */ + +struct Cxx { + const struct Cxx *next; +}; + +@interface ObjC { + const struct Cxx *obj; +} +- (ObjC *)initWithCxx: (struct Cxx *const)c and: (const struct Cxx *)d; +@end + +@implementation ObjC +- (ObjC *)initWithCxx: (struct Cxx *const)c and: (const struct Cxx *)d { + obj = d; + return self; +} +@end + +/* { dg-final { scan-assembler "@\[0-9\]+@0:\[0-9\]+r\\^{Cxx=\\^r{Cxx}}\[0-9\]+\\^r{Cxx}" } } */ diff --git a/gcc/testsuite/objc.dg/extra-semi.m b/gcc/testsuite/objc.dg/extra-semi.m new file mode 100644 index 00000000000..96d31b806d0 --- /dev/null +++ b/gcc/testsuite/objc.dg/extra-semi.m @@ -0,0 +1,10 @@ +/* APPLE LOCAL file Objective-C++ */ +/* Allow extra semicolons in between method declarations, + for old times' sake. */ +/* { dg-do compile } */ + +@interface Foo + -(Foo *) expiration; + -(void) setExpiration:(Foo *) date;; + -(int) getVersion; +@end diff --git a/gcc/testsuite/objc.dg/fix-and-continue-1.m b/gcc/testsuite/objc.dg/fix-and-continue-1.m new file mode 100644 index 00000000000..7bfc8a13776 --- /dev/null +++ b/gcc/testsuite/objc.dg/fix-and-continue-1.m @@ -0,0 +1,91 @@ +/* APPLE LOCAL file mainline */ +/* Fix and continue should not interfere with computation of + local (static) function addresses. */ +/* Author: Ziemowit Laski <zlaski@apple.com> */ + +/* { dg-do run { target *-*-darwin* } } */ +/* { dg-options "-mfix-and-continue" } */ + +#include <objc/Object.h> +#include <stdlib.h> + +@class MyTarget, MySet; + +int global_value = 0; + +@interface MyTargetBuildContext : Object +{ + MyTarget * _target; + unsigned _cacheInvalDisableCount; + BOOL _cacheInvalidationNeeded; + unsigned short _isCreatingDependencies:1; + unsigned short _isCreatingHeadermap:1; + unsigned short _haveAddedIdleTimeInvoc:1; + BOOL _hasSetUpBuildSettings; +} +- (id)initWithTarget:(MyTarget *)target; +- (MyTarget *)target; +@end + +@interface MyTargetBuildContext (PrivateMethods) ++ (MySet *)_headerFileExtensions; +@end + +@interface MyCountedSet: Object { +@public + int cardinality; +} +- (id)init; +- (id)sortedArrayUsingFunction:(int (*)(id, id, void *))comparator with:(int)value; +@end + +@implementation MyCountedSet +- (id)init { + cardinality = 5; + global_value = 17; + return self; +} +- (id)sortedArrayUsingFunction:(int (*)(id, id, void *))comparator with:(int)value { + if(value == comparator(self, self, self)) + return self; + return nil; +} +@end + +@implementation MyTargetBuildContext : Object +- (id)initWithTarget:(MyTarget *)target +{ + self = [super init]; + return self; +} +- (MyTarget *)target +{ + return _target; +} + +static int _MyCompareObjectsByDecreasingSetCount (id object1, id object2, MyCountedSet * countedSet) +{ + global_value = 5; + return countedSet->cardinality; +} ++ (MySet *)_headerFileExtensions +{ + MySet * _headerFileExtensions = 0; + return _headerFileExtensions; +} +- (void)_recomputeHeadermap +{ + MyCountedSet *set = [MyCountedSet new]; + int (*functionPointer)(id, id, void *) = (int (*)(id, id, void *))_MyCompareObjectsByDecreasingSetCount; + id result = [set sortedArrayUsingFunction:functionPointer with:5]; +} +@end + +int main(void) { + MyTargetBuildContext *ctx = [MyTargetBuildContext new]; + [ctx _recomputeHeadermap]; + if (global_value != 5) + abort(); + + return 0; +} diff --git a/gcc/testsuite/objc.dg/isa-field-1.m b/gcc/testsuite/objc.dg/isa-field-1.m new file mode 100644 index 00000000000..7afbafe7508 --- /dev/null +++ b/gcc/testsuite/objc.dg/isa-field-1.m @@ -0,0 +1,44 @@ +/* APPLE LOCAL file Objective-C */ +/* Ensure there are no bizarre difficulties with accessing the 'isa' field of objects. */ +/* { dg-do compile } */ + +#include <objc/Object.h> + +@interface Object (Test) +- (Class) test1: (id)object; +@end + +@interface Derived: Object +- (Class) test2: (id)object; +@end + +@implementation Object (Test) + +Class test1(id object) { + Class cls = object->isa; + return cls; +} +- (Class) test1: (id)object { + Class cls = object->isa; + return cls; +} + +@end + +@implementation Derived + +Class test2(id object) { + Class cls = object->isa; + return cls; +} +- (Class) test2: (id)object { + Class cls = object->isa; + return cls; +} + +@end + +Class test3(id object) { + Class cls = object->isa; + return cls; +} diff --git a/gcc/testsuite/objc.dg/lookup-1.m b/gcc/testsuite/objc.dg/lookup-1.m new file mode 100644 index 00000000000..de20c1d84f3 --- /dev/null +++ b/gcc/testsuite/objc.dg/lookup-1.m @@ -0,0 +1,55 @@ +/* APPLE LOCAL file Objective-C++ */ +/* { dg-do run } */ + +#include <objc/Object.h> +#include <stdlib.h> + +typedef struct MyWidget { + int a; +} MyWidget; + +MyWidget gWidget = { 17 }; + +@protocol MyProto +- (MyWidget *)widget; +@end + +@interface Foo: Object +@end + +@interface Bar: Foo <MyProto> +@end + +@interface Container: Object ++ (MyWidget *)elementForView:(Foo *)view; +@end + +@implementation Foo +@end + +@implementation Bar +- (MyWidget *)widget { + return &gWidget; +} +@end + +@implementation Container ++ (MyWidget *)elementForView:(Foo *)view +{ + MyWidget *widget = nil; + if ([view conformsTo:@protocol(MyProto)]) { + widget = [(Foo <MyProto> *)view widget]; + } + return widget; +} +@end + +int main(void) { + id view = [Bar new]; + MyWidget *w = [Container elementForView: view]; + + if (!w || w->a != 17) + abort (); + + return 0; +} diff --git a/gcc/testsuite/objc.dg/lvalue-cast-1.m b/gcc/testsuite/objc.dg/lvalue-cast-1.m new file mode 100644 index 00000000000..f2575efc631 --- /dev/null +++ b/gcc/testsuite/objc.dg/lvalue-cast-1.m @@ -0,0 +1,32 @@ +/* APPLE LOCAL file non lvalue assign */ +/* { dg-do compile } */ +/* { dg-options "-fnon-lvalue-assign" } */ + +#include <objc/Object.h> + +typedef struct _NSPoint { + float x; + float y; +} NSPoint; +typedef NSPoint *NSPointPointer; +typedef NSPoint *NSPointArray; +typedef struct _NSSize { + float width; + float height; +} NSSize; +typedef struct _NSRect { + NSPoint origin; + NSSize size; +} NSRect; + +@interface NSLayoutManager: Object { + NSRect *_cachedRectArray; +} +- (void)_growCachedRectArrayToSize:(unsigned)newSize; +@end + +@implementation NSLayoutManager +- (void)_growCachedRectArrayToSize:(unsigned)newSize { + ( NSRect *)_cachedRectArray = nil; /* { dg-warning "target of assignment not really an lvalue" } */ +} +@end diff --git a/gcc/testsuite/objc.dg/method-15.m b/gcc/testsuite/objc.dg/method-15.m new file mode 100644 index 00000000000..e7ebf7f314f --- /dev/null +++ b/gcc/testsuite/objc.dg/method-15.m @@ -0,0 +1,56 @@ +/* APPLE LOCAL file */ +/* Test if prior method lookup at method @implementation time is not + overly aggressive, leading to methods being found in other classes. */ +/* Author: Ziemowit Laski <zlaski@apple.com>. */ +/* { dg-do compile } */ + +#include <objc/Object.h> + +@class NSString; + +@protocol NSMenuItem ++ (void)setUsesUserKeyEquivalents:(BOOL)flag; ++ (BOOL)usesUserKeyEquivalents; +@end + +@interface NSMenuItem : Object <NSMenuItem> { + @private + id _menu; +} +@end + +@interface NSResponder : Object <NSMenuItem> +{ + id _nextResponder; +} +@end + +@interface Object(NSMenuValidation) +- (BOOL)validateMenuItem:(id <NSMenuItem>)menuItem; +@end + +@interface NSResponder (NSStandardKeyBindingMethods) +- (void)insertText:(id)insertString; +- (void)doCommandBySelector:(SEL)aSelector; +@end + +@interface NSView : NSResponder +{ + id _superview; + id _subviews; +} +@end + +@interface SKTGraphicView : NSView { + @private + float _gridSpacing; +} +@end + +@implementation SKTGraphicView +- (BOOL)validateMenuItem:(NSMenuItem *)item { + return (BOOL)1; +} +- (void)insertText:(NSString *)str { +} +@end diff --git a/gcc/testsuite/objc.dg/method-16.m b/gcc/testsuite/objc.dg/method-16.m new file mode 100644 index 00000000000..cbe4710ed2c --- /dev/null +++ b/gcc/testsuite/objc.dg/method-16.m @@ -0,0 +1,24 @@ +/* APPLE LOCAL file Objective-C */ +/* Do not warn about "slightly" mismatched method signatures if + -Wstrict-selector-match is off. */ +/* { dg-do compile } */ +/* { dg-options "-Wno-strict-selector-match" } */ + +#include <objc/objc.h> + +@interface Base +- (id) meth1: (Base *)arg1; +- (id) window; +@end + +@interface Derived: Base +- (id) meth1: (Derived *)arg1; +- (Base *)window; +@end + +void foo(void) { + id r; + + [r meth1:r]; + [r window]; +} diff --git a/gcc/testsuite/objc.dg/method-17.m b/gcc/testsuite/objc.dg/method-17.m new file mode 100644 index 00000000000..a4e68539063 --- /dev/null +++ b/gcc/testsuite/objc.dg/method-17.m @@ -0,0 +1,26 @@ +/* APPLE LOCAL file Objective-C */ +/* Test for spurious "may or may not return a value" warnings. */ +/* { dg-do compile } */ +/* { dg-options "-Wextra" } */ + +#include <objc/Object.h> + +@interface Foo: Object +- (id) meth1; +- (void) meth2; +@end + +extern int bar; + +@implementation Foo +- (id) meth1 { + if (bar) + return [Object new]; + return; +} /* { dg-warning "this function may return with or without a value" } */ +- (void) meth2 { + if (!bar) + return; + bar = 0; +} /* { dg-bogus "this function may return with or without a value" } */ +@end diff --git a/gcc/testsuite/objc.dg/method-18.m b/gcc/testsuite/objc.dg/method-18.m new file mode 100644 index 00000000000..12e79a181f7 --- /dev/null +++ b/gcc/testsuite/objc.dg/method-18.m @@ -0,0 +1,30 @@ +/* APPLE LOCAL file Objective-C */ +/* Do not warn about "slightly" mismatched method signatures if + -Wstrict-selector-match is off. */ +/* { dg-do compile } */ +/* { dg-options "-Wno-strict-selector-match" } */ + +#include <objc/objc.h> + +typedef enum { en1_1, en1_2 } En1; +typedef enum { en2_1, en2_2 } En2; +typedef struct { int a, b; } St1; +typedef struct { unsigned a, b; } St2; + +@interface Base +- (id) meth1: (En1)arg1; +- (St1) window; +@end + +@interface Derived: Base +- (id) meth1: (En2)arg1; +- (St2)window; +@end + +void foo(void) { + id r; + En1 en; + + [r meth1:en]; + [r window]; +} diff --git a/gcc/testsuite/objc.dg/method-19.m b/gcc/testsuite/objc.dg/method-19.m new file mode 100644 index 00000000000..32fb8cda0ea --- /dev/null +++ b/gcc/testsuite/objc.dg/method-19.m @@ -0,0 +1,17 @@ +/* APPLE LOCAL file Objective-C */ +/* The following should NOT generate "may not respond to" warnings, since a forward-declared + @class (instance) should be treated like a 'Class') ('id'). */ +/* { dg-do compile } */ + +#include <objc/Object.h> + +@class NotKnown; + +void foo(NotKnown *n) { + [NotKnown new]; + [n nonexistent_method]; /* { dg-warning "no .\\-nonexistent_method. method found" } */ +} + +/* { dg-warning "Messages without a matching method signature" "" { target *-*-* } 0 } */ +/* { dg-warning "will be assumed to return .id. and accept" "" { target *-*-* } 0 } */ +/* { dg-warning ".\.\.\.. as arguments" "" { target *-*-* } 0 } */ diff --git a/gcc/testsuite/objc.dg/method-5.m b/gcc/testsuite/objc.dg/method-5.m index 37677a1ccaa..b79ef9b0c36 100644 --- a/gcc/testsuite/objc.dg/method-5.m +++ b/gcc/testsuite/objc.dg/method-5.m @@ -11,8 +11,10 @@ void foo(UnderSpecified *u, NotAClass *n) { [n nonexistent_method]; /* { dg-warning "invalid receiver type" } */ /* { dg-warning "no .\\-nonexistent_method. method found" "" { target *-*-* } 11 } */ [NotAClass nonexistent_method]; /* { dg-error ".NotAClass. is not an Objective\\-C class name or alias" } */ - [u nonexistent_method]; /* { dg-warning ".UnderSpecified. may not respond to .\\-nonexistent_method." } */ - [UnderSpecified nonexistent_method]; /* { dg-warning ".UnderSpecified. may not respond to .\\+nonexistent_method." } */ + /* APPLE LOCAL begin Objective-C */ + [u nonexistent_method]; /* { dg-warning "no .\\-nonexistent_method. method found" } */ + [UnderSpecified nonexistent_method]; /* { dg-warning "no .\\+nonexistent_method. method found" } */ + /* APPLE LOCAL end Objective-C */ } /* { dg-warning "Messages without a matching method signature" "" { target *-*-* } 0 } */ diff --git a/gcc/testsuite/objc.dg/method-6.m b/gcc/testsuite/objc.dg/method-6.m index a4c1323fac8..d2996dface7 100644 --- a/gcc/testsuite/objc.dg/method-6.m +++ b/gcc/testsuite/objc.dg/method-6.m @@ -1,5 +1,5 @@ -/* Check that sending messages to variables of type 'Class' does not involve instance methods, - unless they reside in root classes. */ +/* APPLE LOCAL file */ +/* Check that sending messages to variables of type 'Class' does not involve instance methods, unless they reside in root classes. */ /* Author: Ziemowit Laski <zlaski@apple.com> */ /* { dg-do compile } */ @@ -29,3 +29,7 @@ void foo(void) { [Class port]; /* { dg-error ".Class. is not an Objective\\-C class name or alias" } */ } + +/* APPLE LOCAL Objective-C */ +/* { dg-options "-Wstrict-selector-match" } */ + diff --git a/gcc/testsuite/objc.dg/method-7.m b/gcc/testsuite/objc.dg/method-7.m index f84759c2169..76930518a50 100644 --- a/gcc/testsuite/objc.dg/method-7.m +++ b/gcc/testsuite/objc.dg/method-7.m @@ -1,5 +1,5 @@ -/* Check if finding multiple signatures for a method is handled gracefully. */ -/* Author: Ziemowit Laski <zlaski@apple.com> */ +/* APPLE LOCAL file */ +/* Check if finding multiple signatures for a method is handled gracefully. Author: Ziemowit Laski <zlaski@apple.com> */ /* { dg-do compile } */ #include <objc/Object.h> @@ -25,3 +25,6 @@ id foo(void) { return obj; } + +/* APPLE LOCAL Objective-C */ +/* { dg-options "-Wstrict-selector-match" } */ diff --git a/gcc/testsuite/objc.dg/method-9.m b/gcc/testsuite/objc.dg/method-9.m index 3921663ec8f..9987748dba0 100644 --- a/gcc/testsuite/objc.dg/method-9.m +++ b/gcc/testsuite/objc.dg/method-9.m @@ -1,5 +1,5 @@ -/* Check if finding multiple signatures for a method is handled gracefully - when method lookup succeeds (see also method-7.m). */ +/* APPLE LOCAL file */ +/* Check if finding multiple signatures for a method is handled gracefully when method lookup succeeds (see also method-7.m). */ /* Contributed by Ziemowit Laski <zlaski@apple.com> */ /* { dg-do compile } */ @@ -41,3 +41,7 @@ return result; } @end + +/* APPLE LOCAL Objective-C */ +/* { dg-options "-Wstrict-selector-match" } */ + diff --git a/gcc/testsuite/objc.dg/next-runtime-1.m b/gcc/testsuite/objc.dg/next-runtime-1.m new file mode 100644 index 00000000000..1fbf70a27d7 --- /dev/null +++ b/gcc/testsuite/objc.dg/next-runtime-1.m @@ -0,0 +1,18 @@ +/* APPLE LOCAL file ObjC GC */ +/* Test that the correct version number (6) is set in the module descriptor + when compiling for the NeXT runtime. */ +/* Author: Ziemowit Laski <zlaski@apple.com> */ +/* { dg-do compile { target *-*-darwin* } } */ +/* { dg-options "-fnext-runtime" } */ + +#include <objc/Object.h> + +@interface FooBar: Object +- (void)boo; +@end + +@implementation FooBar +- (void)boo { } +@end + +/* { dg-final { scan-assembler "L_OBJC_MODULES:\n\[ \t\]*\.long\t6\n" } } */ diff --git a/gcc/testsuite/objc.dg/no-extra-load.m b/gcc/testsuite/objc.dg/no-extra-load.m new file mode 100644 index 00000000000..4e6a9f3b6e3 --- /dev/null +++ b/gcc/testsuite/objc.dg/no-extra-load.m @@ -0,0 +1,5 @@ +/* APPLE LOCAL file 3926484 */ +/* { dg-do compile } */ +#import <Foundation/Foundation.h> +main() { [NSObject new]; } +/* { dg-final { scan-assembler-not "L_objc_msgSend\\\$non_lazy_ptr" } } */ diff --git a/gcc/testsuite/objc.dg/objc-fast-1.m b/gcc/testsuite/objc.dg/objc-fast-1.m new file mode 100644 index 00000000000..6db7c38beec --- /dev/null +++ b/gcc/testsuite/objc.dg/objc-fast-1.m @@ -0,0 +1,24 @@ +/* APPLE LOCAL file ObjC direct dispatch */ +/* A compile-only test for insertion of 'bla' comm page jumps. */ +/* Developed by Ziemowit Laski <zlaski@apple.com> */ +/* { dg-do compile { target powerpc*-*-darwin* } } */ +/* { dg-options "-fnext-runtime -fobjc-gc -fobjc-direct-dispatch -Wassign-intercept" } */ + +#include <objc/Object.h> + +@interface Derived: Object { +@public + Object *other; +} +@end + +void foo(void) { + Derived *o = [Derived new]; + o->other = 0; /* { dg-warning "instance variable assignment has been intercepted" } */ +} + +/* { dg-final { scan-assembler-not "objc_msgSend" } } */ +/* { dg-final { scan-assembler-not "objc_assign_ivar" } } */ + +/* { dg-final { scan-assembler "bla.*fffeff00" } } */ +/* { dg-final { scan-assembler "bla.*fffefec0" } } */ diff --git a/gcc/testsuite/objc.dg/objc-fast-2.m b/gcc/testsuite/objc.dg/objc-fast-2.m new file mode 100644 index 00000000000..61e97adad3a --- /dev/null +++ b/gcc/testsuite/objc.dg/objc-fast-2.m @@ -0,0 +1,29 @@ +/* APPLE LOCAL file ObjC direct dispatch */ +/* A compile-only test for insertion of 'ba' sibcall comm page jumps. */ +/* Developed by Ziemowit Laski <zlaski@apple.com> */ +/* { dg-do compile { target powerpc*-*-darwin* } } */ +/* { dg-options "-fnext-runtime -fobjc-gc -fobjc-direct-dispatch -Wno-assign-intercept -O2" } */ + +#include <objc/Object.h> + +@interface Derived: Object { +@public + Object *other; +} +@end + +void foo(void) { + Derived *o; + o->other = 0; /* sibcall to objc_assign_ivar_Fast() */ +} + +void bar(void) { + Derived *o = nil; + [Derived new]; /* sibcall to objc_msgSend_Fast() */ +} + +/* { dg-final { scan-assembler-not "objc_msgSend" } } */ +/* { dg-final { scan-assembler-not "objc_assign_ivar" } } */ + +/* { dg-final { scan-assembler "ba.*fffeff00" } } */ +/* { dg-final { scan-assembler "ba.*fffefec0" } } */ diff --git a/gcc/testsuite/objc.dg/objc-fast-3.m b/gcc/testsuite/objc.dg/objc-fast-3.m new file mode 100644 index 00000000000..fc57f831eef --- /dev/null +++ b/gcc/testsuite/objc.dg/objc-fast-3.m @@ -0,0 +1,33 @@ +/* APPLE LOCAL file ObjC direct dispatch */ +/* A compile-only test for insertion of 'bla' and 'ba' sibcall comm page jumps + for methods returning 'void'. */ +/* Developed by Ziemowit Laski <zlaski@apple.com> */ +/* { dg-do compile { target powerpc*-*-darwin* } } */ +/* { dg-options "-fnext-runtime -fobjc-gc -fobjc-direct-dispatch -Wno-assign-intercept -O2" } */ + +#include <objc/Object.h> + +@interface Derived: Object { +@public + Object *other; +} +- (void) do_nothing; +@end + +int a; + +void foo(void) { + Derived *o; + [o do_nothing]; /* objc_msgSend_Fast() */ + a = 2; +} + +void bar(void) { + Derived *o = nil; + [o do_nothing]; /* sibcall to objc_msgSend_Fast() */ +} + +/* { dg-final { scan-assembler-not "objc_msgSend" } } */ + +/* { dg-final { scan-assembler "bla.*fffeff00" } } */ +/* { dg-final { scan-assembler "ba.*fffeff00" } } */ diff --git a/gcc/testsuite/objc.dg/objc-fast-4.m b/gcc/testsuite/objc.dg/objc-fast-4.m new file mode 100644 index 00000000000..67e8a998bc4 --- /dev/null +++ b/gcc/testsuite/objc.dg/objc-fast-4.m @@ -0,0 +1,13 @@ +/* APPLE LOCAL file ObjC direct dispatch */ +/* Check that 4015820 is fixed. That does not appear except + with -O0, so the sibcall case cannot occur. */ +/* { dg-do compile { target powerpc*-*-darwin* } } */ +/* { dg-options "-O0 -fobjc-direct-dispatch" } */ +#include <objc/Object.h> + +void foo(void) { + Object *o; + [o++ free]; +} +/* { dg-final { scan-assembler-not "objc_msgSend" } } */ +/* { dg-final { scan-assembler "bla.*fffeff00" } } */ diff --git a/gcc/testsuite/objc.dg/objc-gc-1.m b/gcc/testsuite/objc.dg/objc-gc-1.m new file mode 100644 index 00000000000..ed9a8b1ac13 --- /dev/null +++ b/gcc/testsuite/objc.dg/objc-gc-1.m @@ -0,0 +1,146 @@ +/* APPLE LOCAL file ObjC GC */ +/* A compile-only test for insertion of write barriers. */ +/* Developed by Ziemowit Laski <zlaski@apple.com> */ +/* { dg-do compile { target *-*-darwin* } } */ +/* { dg-options "-fnext-runtime -fobjc-gc -Wassign-intercept" } */ + +#ifndef __OBJC_GC__ +#error Missing __OBJC_GC__ manifest constant +#endif + +#include <objc/Object.h> + +@class Underspecified; +@class MyClass; + +@interface AnotherClass: Object { +@public + __strong void *storage; + MyClass *SomeObj; +} +- (id)assignObj:(id)obj; +@end + +struct Struct1 { + MyClass *someobj; + void *obj2; + __strong void *obj3; +}; + +struct Struct1 *str1a, str1aa; +__strong struct Struct1 *str1b, str1bb, **str1c, *str1d[3][3]; + +extern MyClass *externFunc(void); + +@interface MyClass: Object { +@public + id ivar1, *ivar1a; + void *ivar2; + __strong void *ivar3; + Underspecified *ivar4[2], **ivar4a; + union { + struct { + Underspecified *data; + const unsigned char *dataBytes; + } d; + struct { + __strong void *storage; + AnotherClass *another; + } s; + } contents; + struct { + struct { + void *yy; + } z; + } y; +} +@end + +@implementation AnotherClass +- (id)assignObj:(id)obj { + static MyClass *m_myclass; + static id *indirect; + str1a = 0; + str1b = 0; /* { dg-warning "global\\/static variable assignment" } */ + str1c = 0; /* { dg-warning "global\\/static variable assignment" } */ + str1d[1][1] = 0; /* { dg-warning "global\\/static variable assignment" } */ + str1a->someobj = 0; /* { dg-warning "strong\\-cast may possibly be needed" } */ + str1b->someobj = 0; /* { dg-warning "strong\\-cast may possibly be needed" } */ + str1aa.someobj = 0; /* { dg-warning "global\\/static variable assignment" } */ + str1bb.someobj = 0; /* { dg-warning "global\\/static variable assignment" } */ + str1a->obj2 = 0; + str1b->obj2 = 0; + str1a->obj3 = 0; /* { dg-warning "strong\\-cast may possibly be needed" } */ + str1b->obj3 = 0; /* { dg-warning "strong\\-cast may possibly be needed" } */ + SomeObj->contents.s.another = 0; /* { dg-warning "instance variable assignment" } */ + obj = 0; + externFunc()->ivar1 = 0; /* { dg-warning "instance variable assignment" } */ + externFunc()->contents.s.another->SomeObj = 0; /* { dg-warning "instance variable assignment" } */ + m_myclass = 0; /* { dg-warning "global\\/static variable assignment" } */ + *indirect = obj; /* { dg-warning "strong\\-cast may possibly be needed" } */ + (__strong id)*indirect = obj; /* { dg-warning "strong\\-cast assignment" } */ + (__strong id)(MyClass *)*indirect = obj; /* { dg-warning "strong\\-cast assignment" } */ + self = 0; + self->isa = 0; /* { dg-warning "instance variable assignment" } */ + return SomeObj = obj; /* { dg-warning "instance variable assignment" } */ +} +@end + +typedef MyClass MyClass1; +@compatibility_alias MyClass2 MyClass; + +MyClass *g_myclass; +MyClass1 *g_myclass1; +MyClass2 *g_myclass2; +MyClass2 **g_myclass2a, ***g_myclass2b; +MyClass2 *g_myclass2c[6], *g_myclass2d[4][5]; +__strong void *g_myclass2e[3]; + +id *g_myid, ***g_myid3; + +void function(void) { + static MyClass *l_myclass; + MyClass2 *l_myclass2; + + g_myclass = 0; /* { dg-warning "global\\/static variable assignment" } */ + l_myclass = 0; /* { dg-warning "global\\/static variable assignment" } */ + g_myclass->ivar1 = 0; /* { dg-warning "instance variable assignment" } */ + *g_myclass->ivar1a = 0; + l_myclass2 = 0; + l_myclass2->ivar1 = 0; /* { dg-warning "instance variable assignment" } */ + (__strong id)*g_myclass->ivar1a = 0; /* { dg-warning "strong\\-cast assignment" } */ + g_myclass->ivar2 = 0; + (__strong void *)g_myclass->ivar2 = 0; /* { dg-warning "strong\\-cast assignment" } */ + g_myclass->ivar3 = 0; /* { dg-warning "instance variable assignment" } */ + l_myclass->ivar4[1] = 0; /* { dg-warning "instance variable assignment" } */ + l_myclass->ivar4a = 0; + *l_myclass->ivar4a = 0; + (__strong id)*l_myclass->ivar4a = 0; /* { dg-warning "strong\\-cast assignment" } */ + l_myclass->contents.d.data = 0; /* { dg-warning "instance variable assignment" } */ + l_myclass->contents.d.dataBytes = 0; + (__strong const unsigned char *)l_myclass->contents.d.dataBytes = 0; /* { dg-warning "strong\\-cast assignment" } */ + l_myclass->contents.s.storage = 0; /* { dg-warning "instance variable assignment" } */ + l_myclass->contents.s.another->SomeObj = 0; /* { dg-warning "instance variable assignment" } */ + l_myclass->contents.s.another->storage = 0; /* { dg-warning "instance variable assignment" } */ + (__strong void *)l_myclass->contents.s.another->storage = 0; /* { dg-warning "strong\\-cast assignment" } */ + g_myclass->y.z.yy = 0; + (__strong void *)g_myclass->y.z.yy = 0; /* { dg-warning "strong\\-cast assignment" } */ + g_myclass1->ivar1 = 0; /* { dg-warning "instance variable assignment" } */ + g_myclass2->ivar1 = 0; /* { dg-warning "instance variable assignment" } */ + (*g_myclass2a)->ivar1 = 0; /* { dg-warning "instance variable assignment" } */ + *g_myid = 0; /* { dg-warning "strong\\-cast may possibly be needed" } */ + ***g_myid3 = 0; /* { dg-warning "strong\\-cast may possibly be needed" } */ + (__strong id)*g_myid = 0; /* { dg-warning "strong\\-cast assignment" } */ + (__strong id)***g_myid3 = 0; /* { dg-warning "strong\\-cast assignment" } */ + g_myclass2[3] = g_myclass1[4]; + g_myclass2a[1] = 0; /* { dg-warning "strong\\-cast may possibly be needed" } */ + g_myclass2b[1][2] = 0; /* { dg-warning "strong\\-cast may possibly be needed" } */ + g_myclass2c[1] = 0; /* { dg-warning "global\\/static variable assignment" } */ + g_myclass2e[1] = 0; /* { dg-warning "global\\/static variable assignment" } */ + g_myclass2d[1][2] = 0; /* { dg-warning "global\\/static variable assignment" } */ + g_myclass2a[1]->ivar1 = 0; /* { dg-warning "instance variable assignment" } */ + g_myclass2b[1][2]->ivar1 = 0; /* { dg-warning "instance variable assignment" } */ + g_myclass2c[1]->ivar1 = 0; /* { dg-warning "instance variable assignment" } */ + g_myclass2d[1][2]->ivar1 = 0; /* { dg-warning "instance variable assignment" } */ +} + diff --git a/gcc/testsuite/objc.dg/objc-gc-2.m b/gcc/testsuite/objc.dg/objc-gc-2.m new file mode 100644 index 00000000000..17c4bd56c08 --- /dev/null +++ b/gcc/testsuite/objc.dg/objc-gc-2.m @@ -0,0 +1,172 @@ +/* APPLE LOCAL file ObjC GC */ +/* A run-time test for insertion of write barriers. */ +/* { dg-do run { target *-*-darwin* } } */ +/* { dg-options "-fnext-runtime -fobjc-gc" } */ + +#include <objc/objc.h> +#include <stdio.h> +#include <stdlib.h> + +typedef const struct __CFDictionary * CFDictionaryRef; + +// callouts to these are generated with cc -fobjc-gc + +int GlobalAssigns; +int IvarAssigns; +int StrongCastAssigns; + + +id objc_assign_global(id value, id *dest) { + ++GlobalAssigns; + return (*dest = value); +} + +id objc_assign_ivar(id value, id dest, unsigned int offset) { + id *slot = (id*) ((char *)dest + offset); + + ++IvarAssigns; + return (*slot = value); +} + +id objc_assign_strongCast(id value, id *dest) { + id base; + + ++StrongCastAssigns ; + return (*dest = value); +} + +// The test case elements; +@class NSObject; +@class NSString; + +typedef struct { + id element; + id elementArray[10]; + __strong CFDictionaryRef cfElement; + __strong CFDictionaryRef cfElementArray[10]; +} struct_with_ids_t; + +@interface Foo { +@public +// assignments to any/all of these fields should generate objc_assign_ivar + __strong CFDictionaryRef dict; + __strong CFDictionaryRef dictArray[3]; + id ivar; + id array[10]; + NSObject *nsobject; + NSString *stringArray[10]; + struct_with_ids_t inner; +} + +@end + +// assignments to these should generate objc_assign_global +id GlobalId; +id GlobalArray[20]; +NSObject *GlobalObject; +NSObject *GlobalObjectArray[20]; +__strong CFDictionaryRef Gdict; +__strong CFDictionaryRef Gdictarray[10]; +struct_with_ids_t GlobalStruct; +struct_with_ids_t GlobalStructArray[10]; + + +// The test cases +void *rhs = 0; + +#define ASSIGNTEST(expr, global) expr = rhs; if (!global) { printf(# expr " is busted\n"); ++counter; } global = 0; + +int testGlobals() { + // Everything in this function generates assign_global intercepts + int counter = 0; + + static id staticGlobalId; + static id staticGlobalArray[20]; + static NSObject *staticGlobalObject; + static NSObject *staticGlobalObjectArray[20]; + static __strong CFDictionaryRef staticGdict; + static __strong CFDictionaryRef staticGdictarray[10]; + static struct_with_ids_t staticGlobalStruct; + static struct_with_ids_t staticGlobalStructArray[10]; + + ASSIGNTEST(GlobalId, GlobalAssigns) // objc_assign_global + ASSIGNTEST(GlobalArray[0], GlobalAssigns) // objc_assign_global + ASSIGNTEST(GlobalObject, GlobalAssigns) // objc_assign_global + ASSIGNTEST(GlobalObjectArray[0], GlobalAssigns) // objc_assign_global + ASSIGNTEST(Gdict, GlobalAssigns) // objc_assign_global + ASSIGNTEST(Gdictarray[1], GlobalAssigns) // objc_assign_global + + ASSIGNTEST(GlobalStruct.element, GlobalAssigns) // objc_assign_global + ASSIGNTEST(GlobalStruct.elementArray[0], GlobalAssigns) // objc_assign_global + ASSIGNTEST(GlobalStruct.cfElement, GlobalAssigns) // objc_assign_global + ASSIGNTEST(GlobalStruct.cfElementArray[0], GlobalAssigns) // objc_assign_global + + ASSIGNTEST(staticGlobalId, GlobalAssigns) // objc_assign_global + ASSIGNTEST(staticGlobalArray[0], GlobalAssigns) // objc_assign_global + ASSIGNTEST(staticGlobalObject, GlobalAssigns) // objc_assign_global + ASSIGNTEST(staticGlobalObjectArray[0], GlobalAssigns) // objc_assign_global + ASSIGNTEST(staticGdict, GlobalAssigns) // objc_assign_global + ASSIGNTEST(staticGdictarray[1], GlobalAssigns) // objc_assign_global + + ASSIGNTEST(staticGlobalStruct.element, GlobalAssigns) // objc_assign_global + ASSIGNTEST(staticGlobalStruct.elementArray[0], GlobalAssigns) // objc_assign_global + ASSIGNTEST(staticGlobalStruct.cfElement, GlobalAssigns) // objc_assign_global + ASSIGNTEST(staticGlobalStruct.cfElementArray[0], GlobalAssigns) // objc_assign_global + + return counter; +} + + +int testIvars() { + Foo *foo = (Foo *)malloc(sizeof(Foo)); // don't call in ObjC + int counter = 0; + + ASSIGNTEST(foo->ivar, IvarAssigns) // objc_assign_ivar + ASSIGNTEST(foo->dict, IvarAssigns) // objc_assign_ivar + ASSIGNTEST(foo->dictArray[0], IvarAssigns) // objc_assign_ivar + ASSIGNTEST(foo->array[0], IvarAssigns) // objc_assign_ivar + ASSIGNTEST(foo->nsobject, IvarAssigns) // objc_assign_ivar + ASSIGNTEST(foo->stringArray[0], IvarAssigns) // objc_assign_ivar + ASSIGNTEST(foo->inner.element, IvarAssigns) // objc_assign_ivar + ASSIGNTEST(foo->inner.elementArray[0], IvarAssigns) // objc_assign_ivar + ASSIGNTEST(foo->inner.cfElement, IvarAssigns) // objc_assign_ivar + ASSIGNTEST(foo->inner.cfElementArray[0], IvarAssigns) // objc_assign_ivar + return counter; +} + +int testStrongCasts() { + id x = nil; + int counter = 0; + typedef struct { @defs(Foo) } Foo_defs; + Foo_defs *foo = (Foo_defs *)malloc(sizeof(Foo)); + + // strong casts should always be issued, even if the compiler could know better + + ASSIGNTEST((__strong id)foo->ivar, StrongCastAssigns) // objc_assign_strongCast + ASSIGNTEST((__strong id)foo->dict, StrongCastAssigns) // objc_assign_strongCast + ASSIGNTEST((__strong id)foo->dictArray[0], StrongCastAssigns) // objc_assign_strongCast + ASSIGNTEST((__strong id)foo->array[0], StrongCastAssigns) // objc_assign_strongCast + ASSIGNTEST((__strong id)foo->nsobject, StrongCastAssigns) // objc_assign_strongCast + ASSIGNTEST((__strong id)foo->stringArray[0], StrongCastAssigns) // objc_assign_strongCast + ASSIGNTEST((__strong id)foo->inner.element, StrongCastAssigns) // objc_assign_strongCast + ASSIGNTEST((__strong id)foo->inner.elementArray[0], StrongCastAssigns) // objc_assign_strongCast + ASSIGNTEST((__strong id)foo->inner.cfElement, StrongCastAssigns) // objc_assign_strongCast + ASSIGNTEST((__strong id)foo->inner.cfElementArray[0], StrongCastAssigns) // objc_assign_strongCast + + + // assignments to declared __strong on plain structure elements shouldn't work + + return counter; +} + +@implementation Foo +@end + +int main(int argc, char *argv[]) { + int errors = 0; + errors += testGlobals(); + errors += testIvars(); + errors += testStrongCasts(); + return(errors != 0); +} + diff --git a/gcc/testsuite/objc.dg/objc-gc-3.m b/gcc/testsuite/objc.dg/objc-gc-3.m new file mode 100644 index 00000000000..217c00b8c2d --- /dev/null +++ b/gcc/testsuite/objc.dg/objc-gc-3.m @@ -0,0 +1,53 @@ +/* APPLE LOCAL file ObjC GC */ +/* A run-time test for insertion of write barriers. */ +/* { dg-do run { target *-*-darwin* } } */ +/* { dg-options "-fnext-runtime -fobjc-gc" } */ + +#include <objc/objc.h> +#include <stdio.h> +#include <stdlib.h> + +// callouts to these are generated with cc -fobjc-gc + +int IvarAssigns; + +id objc_assign_ivar(id value, id dest, unsigned int offset) { + id *slot = (id*) ((char *)dest + offset); + + ++IvarAssigns; + return (*slot = value); +} + +// The test case elements; +@class NSObject; + +@interface Foo { +@public +// assignments to any/all of these fields should generate objc_assign_ivar + Foo *obj[20]; + short idx[5]; +} +@end + +int testIvars() { + Foo *foo = (Foo *)calloc(1,sizeof(Foo)); // don't call in ObjC + int counter = 0, errors = 0; + #define ASSIGNTEST(expr, global) expr = foo; if (!global) { printf(# expr " is busted\n"); ++errors; } global = 0; + + ASSIGNTEST(foo->obj[5], IvarAssigns) // objc_assign_ivar + ASSIGNTEST(foo->obj[++counter], IvarAssigns) // objc_assign_ivar + foo->idx[++counter] = 15; + ASSIGNTEST(foo->obj[foo->idx[2]], IvarAssigns) // objc_assign_ivar + + if (foo->obj[5] != foo || foo->obj[1] != foo || foo->obj[15] != foo) + abort(); + + return errors; +} + +@implementation Foo +@end + +int main(int argc, char *argv[]) { + return testIvars(); +} diff --git a/gcc/testsuite/objc.dg/objc.c b/gcc/testsuite/objc.dg/objc.c new file mode 100644 index 00000000000..748111c26eb --- /dev/null +++ b/gcc/testsuite/objc.dg/objc.c @@ -0,0 +1,6 @@ +/* APPLE LOCAL file -ObjC */ + +/* { dg-do compile } */ +/* { dg-options "-ObjC" } */ + +@class foo; diff --git a/gcc/testsuite/objc.dg/pascal-strings-1.m b/gcc/testsuite/objc.dg/pascal-strings-1.m new file mode 100644 index 00000000000..477b94bbff2 --- /dev/null +++ b/gcc/testsuite/objc.dg/pascal-strings-1.m @@ -0,0 +1,20 @@ +/* APPLE LOCAL file pascal strings */ +/* Ensure that there are no warnings or errors issued when a Pascal string is used to + initialize an array and the NUL terminator does not fit. */ +/* Author: Ziemowit Laski <zlaski@apple.com> */ + +/* { dg-do compile } */ +/* { dg-options "-fpascal-strings" } */ + +typedef unsigned char Str15[16]; + +Str15 ggg = "\p012345678901234"; +Str15 hhh = "\p0123456789012345"; /* { dg-warning "initializer.string for array of chars is too long" } */ + +int foo(void) +{ + Str15 sss = "\p012345678901234"; + Str15 ttt = "\p0123456789012345"; /* { dg-warning "initializer.string for array of chars is too long" } */ + + return 0; +} diff --git a/gcc/testsuite/objc.dg/pragma-1.m b/gcc/testsuite/objc.dg/pragma-1.m new file mode 100644 index 00000000000..b086863a997 --- /dev/null +++ b/gcc/testsuite/objc.dg/pragma-1.m @@ -0,0 +1,24 @@ +/* APPLE LOCAL file Objective-C++ */ +/* It is OK to use #pragma inside @implementation body. This test checks that. */ +/* Ziemowit Laski <zlaski@apple.com>. */ + +@interface A +{ + int p; +} ++(int) foo; +-(int) bar; +@end + +@implementation A +#pragma mark - +#pragma mark init / dealloc ++ (int)foo { + return 1; +} +#pragma mark - +#pragma mark Private Functions +- (int)bar { + return 2; +} +@end diff --git a/gcc/testsuite/objc.dg/selector-2.m b/gcc/testsuite/objc.dg/selector-2.m index 5584f1511b6..e73868a92d6 100644 --- a/gcc/testsuite/objc.dg/selector-2.m +++ b/gcc/testsuite/objc.dg/selector-2.m @@ -1,5 +1,6 @@ /* Test that we don't ICE when issuing a -Wselector warning. */ -/* { dg-options "-Wselector -fgnu-runtime" } */ +/* APPLE LOCAL Objective-C */ +/* { dg-options "-Wselector" } */ /* { dg-do compile } */ #include <objc/Object.h> @@ -10,7 +11,8 @@ -(void) foo { SEL a; - a = @selector(b1ar); + /* APPLE LOCAL Objective-C */ + a = @selector(b1ar); /* { dg-warning "creating selector for nonexistent method .b1ar." } */ } -@end /* { dg-warning "creating selector for nonexistent method .b1ar." } */ - +/* APPLE LOCAL Objective-C */ +@end diff --git a/gcc/testsuite/objc.dg/stabs-1.m b/gcc/testsuite/objc.dg/stabs-1.m index 9c38b916728..cb8a6d26269 100644 --- a/gcc/testsuite/objc.dg/stabs-1.m +++ b/gcc/testsuite/objc.dg/stabs-1.m @@ -2,7 +2,7 @@ /* Contributed by Ziemowit Laski <zlaski@apple.com> */ /* { dg-do compile } */ -/* { dg-skip-if "No stabs" { mmix-*-* *-*-aix* alpha*-*-* ia64-*-* } { "*" } { "" } } */ +/* { dg-skip-if "No stabs" { mmix-*-* *-*-aix* alpha*-*-* hppa*64*-*-* ia64-*-* } { "*" } { "" } } */ /* { dg-options "-gstabs" } */ @interface MyClass @@ -15,4 +15,4 @@ } @end -/* { dg-final { scan-assembler ".text\"?\n\t.stabs.*100,0,0,(\\.)?L?Letext\[0-9\]*\n(\\.)?L?Letext" } } */ +/* { dg-final { scan-assembler "(.SUBSPA.*\[\$\]CODE\[\$\]|.text\"?)\n\t.stabs.*100,0,0,(\\.)?L?L\[\$\]?etext\[0-9\]*\n(\\.)?L?L\[\$\]?etext" } } */ diff --git a/gcc/testsuite/objc.dg/stubify-1.m b/gcc/testsuite/objc.dg/stubify-1.m new file mode 100644 index 00000000000..2d6b541d571 --- /dev/null +++ b/gcc/testsuite/objc.dg/stubify-1.m @@ -0,0 +1,33 @@ +/* APPLE LOCAL file Radar 4055183 */ +/* All calls must be properly stubified. Complain about any "call + _objc_msgSend<end-of-line>" without the $stub suffix. */ +/* { dg-do compile { target *-*-darwin* } } */ +/* { dg-options "-Os -mdynamic-no-pic" } */ + +typedef struct objc_object { } *id ; +int x = 41 ; +extern id objc_msgSend(id self, char * op, ...); +extern int bogonic (int, int, int) ; +@interface Document {} +- (Document *) window; +- (Document *) class; +- (Document *) close; +@end +@implementation Document +- (Document *) class { } +- (Document *) close { } +- (Document *) window { } +- (void)willEndCloseSheet:(void *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo { + [[self window] close]; + ((void (*)(id, char *, int))objc_msgSend)([self class], (char *)contextInfo, 1); + ((void (*)(id, char *, int))bogonic)([self class], (char *)contextInfo, 1); + bogonic (3, 4, 5); + x++; +} +@end + +/* { dg-final { scan-assembler-not "\(bl|call\)\[ \t\]+_objc_msgSend\n" } } */ +/* { dg-final { scan-assembler "\(bl|call\)\[ \t\]+L_objc_msgSend\\\$stub\n" } } */ +/* { dg-final { scan-assembler-not "\(bl|call\)\[ \t\]+_bogonic\n" } } */ +/* { dg-final { scan-assembler "\(bl|call\)\[ \t\]+L_bogonic\\\$stub\n" } } */ +/* { dg-final { scan-assembler-not "\\\$non_lazy_ptr" } } */ diff --git a/gcc/testsuite/objc.dg/stubify-2.m b/gcc/testsuite/objc.dg/stubify-2.m new file mode 100644 index 00000000000..9fb5dc04394 --- /dev/null +++ b/gcc/testsuite/objc.dg/stubify-2.m @@ -0,0 +1,30 @@ +/* APPLE LOCAL file Radar 4055183 */ +/* All calls must be properly stubified. */ +/* Testcase extracted from TextEdit:Document.m. */ +/* { dg-do compile { target *-*-darwin* } } */ +/* { dg-options "-mdynamic-no-pic -fdump-rtl-expand" } */ +typedef struct objc_object { } *id ; +int x = 41 ; +extern id objc_msgSend(id self, char * op, ...); +extern int bogonic (int, int, int) ; +@interface Document {} +- (Document *) window; +- (Document *) class; +- (Document *) close; +@end +@implementation Document +- (Document *) class { } +- (Document *) close { } +- (Document *) window { } +- (void)willEndCloseSheet:(void *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo { + [[self window] close]; + ((void (*)(id, char *, int))objc_msgSend)([self class], (char *)contextInfo, 1); + ((void (*)(id, char *, int))bogonic)([self class], (char *)contextInfo, 1); + bogonic (3, 4, 5); + x++; +} +@end + +/* Any symbol_ref of an un-stubified objc_msgSend is an error; look + for "objc_msgSend" in quotes, without the $stub suffix. */ +/* { dg-final { scan-file-not stubify-2.m.00.expand "symbol_ref.*\"objc_msgSend\"" } } */ diff --git a/gcc/testsuite/objc.dg/super-class-4.m b/gcc/testsuite/objc.dg/super-class-4.m new file mode 100644 index 00000000000..bc9d9e38c87 --- /dev/null +++ b/gcc/testsuite/objc.dg/super-class-4.m @@ -0,0 +1,35 @@ +/* APPLE LOCAL file Objective-C */ +/* Bail out gracefully if attempting to derive from a class that has only been + forward-declared (via @class). Conversely, @compatibility_alias declarations + should be traversed to find the @interface. */ +/* { dg-do compile } */ + +#include <objc/Object.h> + +@class MyWpModule; + +@compatibility_alias MyObject Object; +@compatibility_alias FictitiousModule MyWpModule; + +@protocol MySelTarget +- (id) meth1; +@end + +@protocol Img +- (id) meth2; +@end + +@interface FunnyModule: FictitiousModule <Img> /* { dg-error ".MyWpModule., superclass of .FunnyModule." } */ +- (id) meth2; +@end + +@interface MyProjWpModule : MyWpModule <MySelTarget, Img> /* { dg-error ".MyWpModule., superclass of .MyProjWpModule." } */ { + id i1, i2; +} +- (id) meth1; +- (id) meth2; +@end + +@interface AnotherModule: MyObject <MySelTarget> +- (id) meth1; +@end diff --git a/gcc/testsuite/objc.dg/super-dealloc-1.m b/gcc/testsuite/objc.dg/super-dealloc-1.m new file mode 100644 index 00000000000..b87af921860 --- /dev/null +++ b/gcc/testsuite/objc.dg/super-dealloc-1.m @@ -0,0 +1,47 @@ +/* APPLE LOCAL file ObjC super dealloc */ +/* Check for warnings about missing [super dealloc] calls. */ +/* Author: Ziemowit Laski <zlaski@apple.com> */ + +/* { dg-do compile } */ + +@interface Foo { + void *isa; +} +- (void) dealloc; +- (void) some_other; +@end + +@interface Bar: Foo { + void *casa; +} +- (void) dealloc; +@end + +@interface Baz: Bar { + void *usa; +} +- (void) dealloc; +@end + +@implementation Foo +- (void) dealloc { + isa = 0; /* Should not warn here. */ +} +- (void) some_other { + isa = (void *)-1; +} +@end + +@implementation Bar +- (void) dealloc { + casa = 0; + [super some_other]; +} /* { dg-warning "method possibly missing a .super dealloc. call" } */ +@end + +@implementation Baz +- (void) dealloc { + usa = 0; + [super dealloc]; /* Should not warn here. */ +} +@end diff --git a/gcc/testsuite/objc.dg/super-dealloc-2.m b/gcc/testsuite/objc.dg/super-dealloc-2.m new file mode 100644 index 00000000000..52361277fe2 --- /dev/null +++ b/gcc/testsuite/objc.dg/super-dealloc-2.m @@ -0,0 +1,47 @@ +/* APPLE LOCAL file ObjC super dealloc */ +/* Check for warnings about missing [super dealloc] calls. */ +/* Author: Ziemowit Laski <zlaski@apple.com> */ + +/* { dg-do compile } */ + +@interface Foo { + void *isa; +} +- (void) dealloc; +- (void) some_other; +@end + +@interface Bar: Foo { + void *casa; +} +- (void) dealloc0; +@end + +@interface Baz: Bar { + void *usa; +} +- (void) dealloc; +@end + +@implementation Foo +- (void) dealloc { + isa = 0; /* Should not warn here. */ +} +- (void) some_other { + isa = (void *)-1; +} +@end + +@implementation Bar +- (void) dealloc0 { + casa = 0; + [super some_other]; /* Should not warn here. */ +} +@end + +@implementation Baz +- (void) dealloc { + usa = 0; + [super dealloc0]; +} /* { dg-warning "method possibly missing a .super dealloc. call" } */ +@end diff --git a/gcc/testsuite/objc.dg/try-catch-6.m b/gcc/testsuite/objc.dg/try-catch-6.m new file mode 100644 index 00000000000..a9d7d147b42 --- /dev/null +++ b/gcc/testsuite/objc.dg/try-catch-6.m @@ -0,0 +1,29 @@ +/* APPLE LOCAL file Objective-C++ */ +/* { dg-do compile } */ +/* { dg-options "-fobjc-exceptions" } */ + +#include <objc/Object.h> + +int main (int argc, const char * argv[]) { + + Object * pool = [Object new]; + int a; + + if ( 1 ) { + + @try { + a = 1; + } + + @catch (Object *e) { + a = 2; + } + + @finally { + a = 3; + } + } + + [pool free]; + return 0; +} diff --git a/gcc/testsuite/objc.dg/try-catch-7.m b/gcc/testsuite/objc.dg/try-catch-7.m new file mode 100644 index 00000000000..4ff02b8f68d --- /dev/null +++ b/gcc/testsuite/objc.dg/try-catch-7.m @@ -0,0 +1,28 @@ +/* APPLE LOCAL file */ +/* Test for graceful compilation of @synchronized statements. */ +/* { dg-do compile } */ +/* { dg-options "-fobjc-exceptions" } */ + +#include <objc/Object.h> + +@interface Derived: Object +- (id) meth; +@end + +@implementation Derived +- (id) meth { + return self; +} + +static Derived* rewriteDict(void) { + static Derived *sDict = 0; + if (sDict == 0) { + @synchronized ([Derived class]) { + if (sDict == 0) + sDict = [Derived new]; + } + } + return sDict; +} +@end + diff --git a/gcc/testsuite/objc.dg/try-catch-8.m b/gcc/testsuite/objc.dg/try-catch-8.m new file mode 100644 index 00000000000..4b879869a2f --- /dev/null +++ b/gcc/testsuite/objc.dg/try-catch-8.m @@ -0,0 +1,65 @@ +/* APPLE LOCAL file Objective-C */ +/* Check that local variables that get modified inside the @try + block survive until the @catch block is reached. */ +/* Developed by Ziemowit Laski <zlaski@apple.com>. */ + +/* { dg-options "-fobjc-exceptions -O2" } */ +/* { dg-do run } */ + +#include <objc/Object.h> +#include <stdlib.h> +#include <stdio.h> + +int gi1 = 9, gi2 = 19; +float gf1 = 9.0, gf2 = 19.0; +id obj2 = nil; + +void foo (int arg1, float *arg2) +{ + int *pi = &gi1; + float *pf = &gf1; + id obj1 = nil; + int local1 = 45, local2 = 47; + float local3 = 3.0, local4 = 4.0; + register int local5 = 15; + static float local6 = 16.0; + + @try { + local1 = 123; + local2 = 345; + local3 = 5.0; + local4 = 6.0; + local5 = 17; + local6 = 18.0; + pi = &gi2; + pf = &gf2; + obj2 = obj1 = [Object new]; + arg1 = 17; + arg2 = &gf2; + + @throw [Object new]; + } + @catch (Object *obj) { + if(local1 != 123 || local2 != 345 || local3 != 5.0 || local4 != 6.0 || local5 != 17 || local6 != 18.0) { + printf("Abort 1\n"); + abort(); + } + if(pi != &gi2 || pf != &gf2) { + printf("Abort 2\n"); + abort(); + } + if(!obj1 || obj1 != obj2) { + printf("Abort 3\n"); + abort(); + } + if(arg1 != 17 || arg2 != &gf2) { + printf("Abort 4\n"); + abort(); + } + } +} + +int main(void) { + foo(15, &gf1); + return 0; +} |