summaryrefslogtreecommitdiffstats
path: root/clang/test
diff options
context:
space:
mode:
Diffstat (limited to 'clang/test')
-rw-r--r--clang/test/Sema/transparent-union.c2
-rw-r--r--clang/test/SemaCXX/flexible-array-test.cpp5
-rw-r--r--clang/test/SemaObjC/flexible-array-arc.m36
-rw-r--r--clang/test/SemaObjC/flexible-array.m288
-rw-r--r--clang/test/SemaObjC/ivar-sem-check-1.m5
-rw-r--r--clang/test/SemaObjCXX/flexible-array.mm37
6 files changed, 370 insertions, 3 deletions
diff --git a/clang/test/Sema/transparent-union.c b/clang/test/Sema/transparent-union.c
index dfbadcfe62c..04811276748 100644
--- a/clang/test/Sema/transparent-union.c
+++ b/clang/test/Sema/transparent-union.c
@@ -102,7 +102,7 @@ union pr15134v2 {
union pr30520v { void b; } __attribute__((transparent_union)); // expected-error {{field has incomplete type 'void'}}
-union pr30520a { int b[]; } __attribute__((transparent_union)); // expected-error {{field has incomplete type 'int []'}}
+union pr30520a { int b[]; } __attribute__((transparent_union)); // expected-error {{flexible array member 'b' in a union is not allowed}}
// expected-note@+1 2 {{forward declaration of 'struct stb'}}
union pr30520s { struct stb b; } __attribute__((transparent_union)); // expected-error {{field has incomplete type 'struct stb'}}
diff --git a/clang/test/SemaCXX/flexible-array-test.cpp b/clang/test/SemaCXX/flexible-array-test.cpp
index 2d74fa52452..f2105ca3613 100644
--- a/clang/test/SemaCXX/flexible-array-test.cpp
+++ b/clang/test/SemaCXX/flexible-array-test.cpp
@@ -66,6 +66,11 @@ union B {
char c[];
};
+class C {
+ char c[]; // expected-error {{flexible array member 'c' with type 'char []' is not at the end of class}}
+ int s; // expected-note {{next field declaration is here}}
+};
+
namespace rdar9065507 {
struct StorageBase {
diff --git a/clang/test/SemaObjC/flexible-array-arc.m b/clang/test/SemaObjC/flexible-array-arc.m
new file mode 100644
index 00000000000..1490329b183
--- /dev/null
+++ b/clang/test/SemaObjC/flexible-array-arc.m
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -fsyntax-only -fobjc-arc -verify -Wno-objc-root-class %s
+// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class -DNOARC %s
+#ifdef NOARC
+// expected-no-diagnostics
+#endif
+
+@interface RetainableArray {
+ id flexible[];
+#ifndef NOARC
+ // expected-error@-2 {{ARC forbids flexible array members with retainable object type}}
+#endif
+}
+@end
+@implementation RetainableArray
+@end
+
+// Emit diagnostic only if have @implementation.
+@interface RetainableArrayWithoutImpl {
+ id flexible[];
+}
+@end
+
+// With ARC flexible array member objects can be only __unsafe_unretained
+@interface UnsafeUnretainedArray {
+ __unsafe_unretained id flexible[];
+}
+@end
+@implementation UnsafeUnretainedArray
+@end
+
+@interface NotObjCLifetimeTypeArray {
+ char flexible[];
+}
+@end
+@implementation NotObjCLifetimeTypeArray
+@end
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
diff --git a/clang/test/SemaObjC/ivar-sem-check-1.m b/clang/test/SemaObjC/ivar-sem-check-1.m
index de038f5487b..48e0a54b628 100644
--- a/clang/test/SemaObjC/ivar-sem-check-1.m
+++ b/clang/test/SemaObjC/ivar-sem-check-1.m
@@ -6,14 +6,15 @@ typedef int FOO();
@interface INTF
{
struct F {} JJ;
- int arr[]; // expected-error {{field has incomplete type}}
+ int arr[]; // expected-error {{flexible array member 'arr' with type 'int []' is not at the end of class}}
struct S IC; // expected-error {{field has incomplete type}}
+ // expected-note@-1 {{next instance variable declaration is here}}
struct T { // expected-note {{previous definition is here}}
struct T {} X; // expected-error {{nested redefinition of 'T'}}
}YYY;
FOO BADFUNC; // expected-error {{field 'BADFUNC' declared as a function}}
int kaka; // expected-note {{previous declaration is here}}
int kaka; // expected-error {{duplicate member 'kaka'}}
- char ch[]; // expected-error {{field has incomplete type}}
+ char ch[];
}
@end
diff --git a/clang/test/SemaObjCXX/flexible-array.mm b/clang/test/SemaObjCXX/flexible-array.mm
new file mode 100644
index 00000000000..5537876c303
--- /dev/null
+++ b/clang/test/SemaObjCXX/flexible-array.mm
@@ -0,0 +1,37 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s
+
+// Test only flexible array member functionality specific to C++.
+
+union VariableSizeUnion {
+ int s;
+ char c[];
+};
+
+@interface LastUnionIvar {
+ VariableSizeUnion flexible;
+}
+@end
+
+@interface NotLastUnionIvar {
+ VariableSizeUnion flexible; // expected-error {{field 'flexible' with variable sized type 'VariableSizeUnion' is not at the end of class}}
+ int last; // expected-note {{next instance variable declaration is here}}
+}
+@end
+
+
+class VariableSizeClass {
+public:
+ int s;
+ char c[];
+};
+
+@interface LastClassIvar {
+ VariableSizeClass flexible;
+}
+@end
+
+@interface NotLastClassIvar {
+ VariableSizeClass flexible; // expected-error {{field 'flexible' with variable sized type 'VariableSizeClass' is not at the end of class}}
+ int last; // expected-note {{next instance variable declaration is here}}
+}
+@end
OpenPOWER on IntegriCloud