diff options
Diffstat (limited to 'test/SemaObjCXX')
-rw-r--r-- | test/SemaObjCXX/Inputs/nullability-completeness-cferror.h | 13 | ||||
-rw-r--r-- | test/SemaObjCXX/Inputs/nullability-consistency-2.h | 2 | ||||
-rw-r--r-- | test/SemaObjCXX/block-variable-move.mm | 43 | ||||
-rw-r--r-- | test/SemaObjCXX/flexible-array.mm | 37 | ||||
-rw-r--r-- | test/SemaObjCXX/noescape.mm | 90 | ||||
-rw-r--r-- | test/SemaObjCXX/nullability-completeness-cferror.mm | 5 | ||||
-rw-r--r-- | test/SemaObjCXX/typo-correction.mm | 53 |
7 files changed, 241 insertions, 2 deletions
diff --git a/test/SemaObjCXX/Inputs/nullability-completeness-cferror.h b/test/SemaObjCXX/Inputs/nullability-completeness-cferror.h new file mode 100644 index 000000000000..4988a7491c25 --- /dev/null +++ b/test/SemaObjCXX/Inputs/nullability-completeness-cferror.h @@ -0,0 +1,13 @@ +@class NSError; + +#pragma clang assume_nonnull begin + +#ifdef USE_MUTABLE +typedef struct __attribute__((objc_bridge_mutable(NSError))) __CFError * CFErrorRef; +#else +typedef struct __attribute__((objc_bridge(NSError))) __CFError * CFErrorRef; +#endif + +void func1(CFErrorRef *error); + +#pragma clang assume_nonnull end diff --git a/test/SemaObjCXX/Inputs/nullability-consistency-2.h b/test/SemaObjCXX/Inputs/nullability-consistency-2.h index 72f22e2ce473..84a1369618af 100644 --- a/test/SemaObjCXX/Inputs/nullability-consistency-2.h +++ b/test/SemaObjCXX/Inputs/nullability-consistency-2.h @@ -6,9 +6,9 @@ void g2(int (^block)(int, int)); // expected-warning{{block pointer is missing a void g3(const id // expected-warning{{missing a nullability type specifier}} + volatile // expected-note@-1 {{insert '_Nullable' if the pointer may be null}} // expected-note@-2 {{insert '_Nonnull' if the pointer should never be null}} - volatile * // expected-warning{{missing a nullability type specifier}} // expected-note@-1 {{insert '_Nullable' if the pointer may be null}} // expected-note@-2 {{insert '_Nonnull' if the pointer should never be null}} diff --git a/test/SemaObjCXX/block-variable-move.mm b/test/SemaObjCXX/block-variable-move.mm new file mode 100644 index 000000000000..e26dffc5d040 --- /dev/null +++ b/test/SemaObjCXX/block-variable-move.mm @@ -0,0 +1,43 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -fobjc-arc -verify -fblocks -Wpessimizing-move -Wredundant-move %s + +// definitions for std::move +namespace std { +inline namespace foo { +template <class T> struct remove_reference { typedef T type; }; +template <class T> struct remove_reference<T&> { typedef T type; }; +template <class T> struct remove_reference<T&&> { typedef T type; }; + +template <class T> typename remove_reference<T>::type &&move(T &&t); +} +} + +class MoveOnly { +public: + MoveOnly() { } + MoveOnly(MoveOnly &&) = default; // expected-note 2 {{copy constructor is implicitly deleted}} + MoveOnly &operator=(MoveOnly &&) = default; + ~MoveOnly(); +}; + +void copyInit() { + __block MoveOnly temp; + MoveOnly temp2 = temp; // expected-error {{call to implicitly-deleted copy constructor of 'MoveOnly'}} + MoveOnly temp3 = std::move(temp); // ok +} + +MoveOnly errorOnCopy() { + __block MoveOnly temp; + return temp; // expected-error {{call to implicitly-deleted copy constructor of 'MoveOnly'}} +} + +MoveOnly dontWarnOnMove() { + __block MoveOnly temp; + return std::move(temp); // ok +} + +class MoveOnlySub : public MoveOnly {}; + +MoveOnly dontWarnOnMoveSubclass() { + __block MoveOnlySub temp; + return std::move(temp); // ok +} diff --git a/test/SemaObjCXX/flexible-array.mm b/test/SemaObjCXX/flexible-array.mm new file mode 100644 index 000000000000..5537876c3039 --- /dev/null +++ b/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 diff --git a/test/SemaObjCXX/noescape.mm b/test/SemaObjCXX/noescape.mm new file mode 100644 index 000000000000..6c5d9897aaf0 --- /dev/null +++ b/test/SemaObjCXX/noescape.mm @@ -0,0 +1,90 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -fblocks -std=c++11 %s +// RUN: %clang_cc1 -fsyntax-only -verify -fblocks -std=c++1z %s + +typedef void (^BlockTy)(); + +struct S { + int i; + void m(); +}; + +void noescapeFunc0(id, __attribute__((noescape)) BlockTy); +void noescapeFunc1(id, [[clang::noescape]] BlockTy); +void noescapeFunc2(__attribute__((noescape)) int *); // expected-note {{previous declaration is here}} +void noescapeFunc3(__attribute__((noescape)) id); +void noescapeFunc4(__attribute__((noescape)) int &); +void noescapeFunc2(int *); // expected-error {{conflicting types for 'noescapeFunc2'}} + +void invalidFunc0(int __attribute__((noescape))); // expected-warning {{'noescape' attribute only applies to pointer arguments}} +void invalidFunc1(int __attribute__((noescape(0)))); // expected-error {{'noescape' attribute takes no arguments}} +void invalidFunc2(int0 *__attribute__((noescape))); // expected-error {{use of undeclared identifier 'int0'; did you mean 'int'?}} +void invalidFunc3(__attribute__((noescape)) int (S::*Ty)); // expected-warning {{'noescape' attribute only applies to pointer arguments}} +void invalidFunc4(__attribute__((noescape)) void (S::*Ty)()); // expected-warning {{'noescape' attribute only applies to pointer arguments}} +int __attribute__((noescape)) g; // expected-warning {{'noescape' attribute only applies to parameters}} + +struct S1 { + virtual void m0(int *__attribute__((noescape))); // expected-note {{parameter of overridden method is annotated with __attribute__((noescape))}} +}; + +struct S2 : S1 { + void m0(int *__attribute__((noescape))) override; +}; + +struct S3 : S1 { + void m0(int *) override; // expected-warning {{parameter of overriding method should be annotated with __attribute__((noescape))}} +}; + +__attribute__((objc_root_class)) +@interface C0 +-(void) m0:(int*)__attribute__((noescape)) p; // expected-note {{parameter of overridden method is annotated with __attribute__((noescape))}} +@end + +@implementation C0 +-(void) m0:(int*)__attribute__((noescape)) p {} +@end + +@interface C1 : C0 +-(void) m0:(int*)__attribute__((noescape)) p; +@end + +@implementation C1 : C0 +-(void) m0:(int*)__attribute__((noescape)) p {} +@end + +@interface C2 : C0 +-(void) m0:(int*) p; // expected-warning {{parameter of overriding method should be annotated with __attribute__((noescape))}} +@end + +@implementation C2 : C0 +-(void) m0:(int*) p {} +@end + +void func0(int *); +void (*fnptr0)(int *); +void (*fnptr1)(__attribute__((noescape)) int *); +template<void (*fn)(int*)> struct S4 {}; +template<void (*fn)(int* __attribute__((noescape)))> struct S5 {}; + +#if __cplusplus < 201406 + // expected-note@-4 {{template parameter is declared here}} + // expected-note@-4 {{template parameter is declared here}} +#endif + +void test0() { + fnptr0 = &func0; + fnptr0 = &noescapeFunc2; + fnptr1 = &func0; // expected-error {{assigning to 'void (*)(__attribute__((noescape)) int *)' from incompatible type 'void (*)(int *)'}} + fnptr1 = &noescapeFunc2; + S4<&func0> e0; + S4<&noescapeFunc2> e1; + S5<&func0> ne0; + +#if __cplusplus < 201406 + // expected-error@-4 {{non-type template argument of type 'void (*)(__attribute__((noescape)) int *)' cannot be converted to a value of type 'void (*)(int *)'}} + // expected-error@-4 {{non-type template argument of type 'void (*)(int *)' cannot be converted to a value of type 'void (*)(__attribute__((noescape)) int *)'}} +#else + // expected-error@-6 {{value of type 'void (*)(int *)' is not implicitly convertible to 'void (*)(__attribute__((noescape)) int *)'}} +#endif + + S5<&noescapeFunc2> ne1; +} diff --git a/test/SemaObjCXX/nullability-completeness-cferror.mm b/test/SemaObjCXX/nullability-completeness-cferror.mm new file mode 100644 index 000000000000..4cea9fba9272 --- /dev/null +++ b/test/SemaObjCXX/nullability-completeness-cferror.mm @@ -0,0 +1,5 @@ +// RUN: %clang_cc1 -fsyntax-only -I %S/Inputs -x objective-c -Wnullability-completeness -Werror -verify %s +// RUN: %clang_cc1 -fsyntax-only -I %S/Inputs -x objective-c -Wnullability-completeness -Werror -verify -DUSE_MUTABLE %s +// expected-no-diagnostics + +#include "nullability-completeness-cferror.h" diff --git a/test/SemaObjCXX/typo-correction.mm b/test/SemaObjCXX/typo-correction.mm index 5e33bfb8cbf0..3f8a082a84a2 100644 --- a/test/SemaObjCXX/typo-correction.mm +++ b/test/SemaObjCXX/typo-correction.mm @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 %s -verify -fsyntax-only +// RUN: %clang_cc1 %s -verify -fsyntax-only -Wno-objc-root-class class ClassA {}; @@ -36,3 +36,54 @@ void invalidNameInIvarAndPropertyBase() { float a = ((InvalidNameInIvarAndPropertyBase*)node)->_a; // expected-error {{use of undeclared identifier 'node'}} float b = ((InvalidNameInIvarAndPropertyBase*)node)._b; // expected-error {{use of undeclared identifier 'node'}} } + +// rdar://problem/33102722 +// Typo correction for a property when it has as correction candidates +// synthesized ivar and a class name, both at the same edit distance. +@class TypoCandidate; + +@interface PropertyType : NSObject +@property int x; +@end + +@interface InterfaceC : NSObject +@property(assign) PropertyType *typoCandidate; // expected-note {{'_typoCandidate' declared here}} +@end + +@implementation InterfaceC +-(void)method { + typoCandidate.x = 0; // expected-error {{use of undeclared identifier 'typoCandidate'; did you mean '_typoCandidate'?}} +} +@end + +// rdar://35172419 +// The scope of 'do-while' ends before typo-correction takes place. + +struct Mat2 { int rows; }; + +@implementation ImplNoInt // expected-warning {{cannot find interface declaration for 'ImplNoInt'}} + +- (void)typoCorrentInDoWhile { + Mat2 tlMat1; // expected-note {{'tlMat1' declared here}} + // Create many scopes to exhaust the cache. + do { + for (int index = 0; index < 2; index++) { + if (true) { + for (int specialTileType = 1; specialTileType < 5; specialTileType++) { + for (int i = 0; i < 10; i++) { + for (double scale = 0.95; scale <= 1.055; scale += 0.05) { + for (int j = 0; j < 10; j++) { + if (1 > 0.9) { + for (int sptile = 1; sptile < 5; sptile++) { + } + } + } + } + } + } + } + } + } while (tlMat.rows); // expected-error {{use of undeclared identifier 'tlMat'; did you mean 'tlMat1'}} +} + +@end |