| // 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 |