diff options
Diffstat (limited to 'clang/test/SemaObjC/flexible-array.m')
| -rw-r--r-- | clang/test/SemaObjC/flexible-array.m | 288 |
1 files changed, 288 insertions, 0 deletions
diff --git a/clang/test/SemaObjC/flexible-array.m b/clang/test/SemaObjC/flexible-array.m new file mode 100644 index 00000000000..68e32d851f6 --- /dev/null +++ b/clang/test/SemaObjC/flexible-array.m @@ -0,0 +1,288 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s + +// # Flexible array member. +// ## Instance variables only in interface. +@interface LastIvar { + char flexible[]; +} +@end + +@interface NotLastIvar { + char flexible[]; // expected-error {{flexible array member 'flexible' with type 'char []' is not at the end of class}} + int last; // expected-note {{next instance variable declaration is here}} +} +@end + +// ## Instance variables in implementation. +@interface LastIvarInImpl +@end +@implementation LastIvarInImpl { + char flexible[]; // expected-warning {{field 'flexible' with variable sized type 'char []' is not visible to subclasses and can conflict with their instance variables}} +} +@end + +@interface NotLastIvarInImpl +@end +@implementation NotLastIvarInImpl { + char flexible[]; // expected-error {{flexible array member 'flexible' with type 'char []' is not at the end of class}} + // expected-warning@-1 {{field 'flexible' with variable sized type 'char []' is not visible to subclasses and can conflict with their instance variables}} + int last; // expected-note {{next instance variable declaration is here}} +} +@end + +@implementation NotLastIvarInImplWithoutInterface { // expected-warning {{cannot find interface declaration for 'NotLastIvarInImplWithoutInterface'}} + char flexible[]; // expected-error {{flexible array member 'flexible' with type 'char []' is not at the end of class}} + // expected-warning@-1 {{field 'flexible' with variable sized type 'char []' is not visible to subclasses and can conflict with their instance variables}} + int last; // expected-note {{next instance variable declaration is here}} +} +@end + +@interface LastIvarInClass_OtherIvarInImpl { + char flexible[]; // expected-error {{flexible array member 'flexible' with type 'char []' is not at the end of class}} +} +@end +@implementation LastIvarInClass_OtherIvarInImpl { + int last; // expected-note {{next instance variable declaration is here}} +} +@end + +// ## Non-instance variables in implementation. +@interface LastIvarInClass_UnrelatedVarInImpl { + char flexible[]; +} +@end +@implementation LastIvarInClass_UnrelatedVarInImpl +int nonIvar; +@end + +// ## Instance variables in class extension. +@interface LastIvarInExtension +@end +@interface LastIvarInExtension() { + char flexible[]; // expected-warning {{field 'flexible' with variable sized type 'char []' is not visible to subclasses and can conflict with their instance variables}} +} +@end + +@interface NotLastIvarInExtension +@end +@interface NotLastIvarInExtension() { + char flexible[]; // expected-error {{flexible array member 'flexible' with type 'char []' is not at the end of class}} + // expected-warning@-1 {{field 'flexible' with variable sized type 'char []' is not visible to subclasses and can conflict with their instance variables}} + int last; // expected-note {{next instance variable declaration is here}} +} +@end + +@interface LastIvarInClass_OtherIvarInExtension { + char flexible[]; // expected-error {{flexible array member 'flexible' with type 'char []' is not at the end of class}} +} +@end +@interface LastIvarInClass_OtherIvarInExtension() { + int last; // expected-note {{next instance variable declaration is here}} +} +@end + +@interface LastIvarInExtension_OtherIvarInExtension +@end +@interface LastIvarInExtension_OtherIvarInExtension() { + int last; // expected-note {{next instance variable declaration is here}} +} +@end +@interface LastIvarInExtension_OtherIvarInExtension() +// Extension without ivars to test we see through such extensions. +@end +@interface LastIvarInExtension_OtherIvarInExtension() { + char flexible[]; // expected-error {{flexible array member 'flexible' with type 'char []' is not at the end of class}} + // expected-warning@-1 {{field 'flexible' with variable sized type 'char []' is not visible to subclasses and can conflict with their instance variables}} +} +@end + +@interface LastIvarInExtension_OtherIvarInImpl +@end +@interface LastIvarInExtension_OtherIvarInImpl() { + char flexible[]; // expected-error {{flexible array member 'flexible' with type 'char []' is not at the end of class}} + // expected-warning@-1 {{field 'flexible' with variable sized type 'char []' is not visible to subclasses and can conflict with their instance variables}} +} +@end +@implementation LastIvarInExtension_OtherIvarInImpl { + int last; // expected-note {{next instance variable declaration is here}} +} +@end + +// ## Instance variables in named categories. +@interface IvarInNamedCategory +@end +@interface IvarInNamedCategory(Category) { + char flexible[]; // expected-error {{instance variables may not be placed in categories}} +} +@end + +// ## Synthesized instance variable. +@interface LastIvarAndProperty { + char _flexible[]; +} +@property char flexible[]; // expected-error {{property cannot have array or function type 'char []'}} +@end + +// ## Synthesize other instance variables. +@interface LastIvar_ExplicitlyNamedPropertyBackingIvarPreceding { + int _elementsCount; + char flexible[]; +} +@property int count; +@end +@implementation LastIvar_ExplicitlyNamedPropertyBackingIvarPreceding +@synthesize count = _elementsCount; +@end + +@interface LastIvar_ImplicitlyNamedPropertyBackingIvarPreceding { + int count; + char flexible[]; +} +@property int count; +@end +@implementation LastIvar_ImplicitlyNamedPropertyBackingIvarPreceding +@synthesize count; +@end + +@interface NotLastIvar_ExplicitlyNamedPropertyBackingIvarLast { + char flexible[]; // expected-error {{flexible array member 'flexible' with type 'char []' is not at the end of class}} +} +@property int count; +@end +@implementation NotLastIvar_ExplicitlyNamedPropertyBackingIvarLast +@synthesize count = _elementsCount; // expected-note {{next synthesized instance variable is here}} +@end + +@interface NotLastIvar_ImplicitlyNamedPropertyBackingIvarLast { + char flexible[]; // expected-error {{flexible array member 'flexible' with type 'char []' is not at the end of class}} +} +@property int count; // expected-note {{next synthesized instance variable is here}} +@end +@implementation NotLastIvar_ImplicitlyNamedPropertyBackingIvarLast +// Test auto-synthesize. +//@synthesize count; +@end + + +// # Variable sized types. +struct Packet { + unsigned int size; + char data[]; +}; + +// ## Instance variables only in interface. +@interface LastStructIvar { + struct Packet flexible; +} +@end + +@interface NotLastStructIvar { + struct Packet flexible; // expected-error {{field 'flexible' with variable sized type 'struct Packet' is not at the end of class}} + int last; // expected-note {{next instance variable declaration is here}} +} +@end + +// ## Instance variables in implementation. +@interface LastStructIvarInImpl +@end +@implementation LastStructIvarInImpl { + struct Packet flexible; // expected-warning {{field 'flexible' with variable sized type 'struct Packet' is not visible to subclasses and can conflict with their instance variables}} +} +@end + +@interface NotLastStructIvarInImpl +@end +@implementation NotLastStructIvarInImpl { + struct Packet flexible; // expected-error {{field 'flexible' with variable sized type 'struct Packet' is not at the end of class}} + // expected-warning@-1 {{field 'flexible' with variable sized type 'struct Packet' is not visible to subclasses and can conflict with their instance variables}} + int last; // expected-note {{next instance variable declaration is here}} +} +@end + +@interface LastStructIvarInClass_OtherIvarInImpl { + struct Packet flexible; // expected-error {{field 'flexible' with variable sized type 'struct Packet' is not at the end of class}} +} +@end +@implementation LastStructIvarInClass_OtherIvarInImpl { + int last; // expected-note {{next instance variable declaration is here}} +} +@end + +// ## Synthesized instance variable. +@interface LastSynthesizeStructIvar +@property int first; +@property struct Packet flexible; // expected-error {{synthesized property with variable size type 'struct Packet' requires an existing instance variable}} +@end +@implementation LastSynthesizeStructIvar +@end + +@interface NotLastSynthesizeStructIvar +@property struct Packet flexible; // expected-error {{synthesized property with variable size type 'struct Packet' requires an existing instance variable}} +@property int last; +@end +@implementation NotLastSynthesizeStructIvar +@end + +@interface LastStructIvarWithExistingIvarAndSynthesizedProperty { + struct Packet _flexible; +} +@property struct Packet flexible; +@end +@implementation LastStructIvarWithExistingIvarAndSynthesizedProperty +@end + + +// # Subclasses. +@interface FlexibleArrayMemberBase { + char flexible[]; // expected-note6 {{'flexible' declared here}} +} +@end + +@interface NoIvarAdditions : FlexibleArrayMemberBase +@end +@implementation NoIvarAdditions +@end + +@interface AddedIvarInInterface : FlexibleArrayMemberBase { + int last; // expected-warning {{field 'last' can overwrite instance variable 'flexible' with variable sized type 'char []' in superclass 'FlexibleArrayMemberBase'}} +} +@end + +@interface AddedIvarInImplementation : FlexibleArrayMemberBase +@end +@implementation AddedIvarInImplementation { + int last; // expected-warning {{field 'last' can overwrite instance variable 'flexible' with variable sized type 'char []' in superclass 'FlexibleArrayMemberBase'}} +} +@end + +@interface AddedIvarInExtension : FlexibleArrayMemberBase +@end +@interface AddedIvarInExtension() { + int last; // expected-warning {{field 'last' can overwrite instance variable 'flexible' with variable sized type 'char []' in superclass 'FlexibleArrayMemberBase'}} +} +@end + +@interface SynthesizedIvar : FlexibleArrayMemberBase +@property int count; +@end +@implementation SynthesizedIvar +@synthesize count; // expected-warning {{field 'count' can overwrite instance variable 'flexible' with variable sized type 'char []' in superclass 'FlexibleArrayMemberBase'}} +@end + +@interface WarnInSubclassOnlyOnce : FlexibleArrayMemberBase { + int last; // expected-warning {{field 'last' can overwrite instance variable 'flexible' with variable sized type 'char []' in superclass 'FlexibleArrayMemberBase'}} +} +@end +@interface WarnInSubclassOnlyOnce() { + int laster; +} +@end +@implementation WarnInSubclassOnlyOnce { + int lastest; +} +@end + +@interface AddedIvarInSubSubClass : NoIvarAdditions { + int last; // expected-warning {{field 'last' can overwrite instance variable 'flexible' with variable sized type 'char []' in superclass 'FlexibleArrayMemberBase'}} +} +@end |

