diff options
| author | Manman Ren <manman.ren@gmail.com> | 2016-09-13 17:41:05 +0000 |
|---|---|---|
| committer | Manman Ren <manman.ren@gmail.com> | 2016-09-13 17:41:05 +0000 |
| commit | c5705bae05590b799c4726c35acf2c7382e0857d (patch) | |
| tree | 61a2bcc0b02f7872b565e61595e5e9198b32cb5f /clang/test | |
| parent | d3e85b98be7a8fb68e235bf6ead69b4bc5e50c42 (diff) | |
| download | bcm5719-llvm-c5705bae05590b799c4726c35acf2c7382e0857d.tar.gz bcm5719-llvm-c5705bae05590b799c4726c35acf2c7382e0857d.zip | |
ObjectiveC Generics: Start using ObjCTypeParamType.
For ObjC type parameter, we used to have TypedefType that is canonicalized to
id or the bound type. We can't represent "T <protocol>" and thus will lose
the type information in the following example:
@interface MyMutableDictionary<KeyType, ObjectType> : NSObject
- (void)setObject:(ObjectType)obj forKeyedSubscript:(KeyType <NSCopying>)key;
@end
MyMutableDictionary<NSString *, NSString *> *stringsByString;
NSNumber *n1, *n2;
stringsByString[n1] = n2;
--> no warning on type mismatch of the key.
To fix the problem, we introduce a new type ObjCTypeParamType that supports
a list of protocol qualifiers.
We create ObjCTypeParamType for ObjCTypeParamDecl when we create
ObjCTypeParamDecl. We also substitute ObjCTypeParamType instead of TypedefType
on an ObjCTypeParamDecl.
rdar://24619481
rdar://25060179
Differential Revision: http://reviews.llvm.org/D23080
llvm-svn: 281358
Diffstat (limited to 'clang/test')
| -rw-r--r-- | clang/test/SemaObjC/kindof.m | 10 | ||||
| -rw-r--r-- | clang/test/SemaObjC/parameterized_classes_subst.m | 33 |
2 files changed, 42 insertions, 1 deletions
diff --git a/clang/test/SemaObjC/kindof.m b/clang/test/SemaObjC/kindof.m index 63ba18fe89b..9d758d3cfb2 100644 --- a/clang/test/SemaObjC/kindof.m +++ b/clang/test/SemaObjC/kindof.m @@ -385,7 +385,7 @@ void testNullability() { @end @interface NSGeneric<ObjectType> : NSObject -- (void)test:(__kindof ObjectType)T; +- (void)test:(__kindof ObjectType)T; // expected-note{{passing argument to parameter 'T' here}} - (void)mapUsingBlock:(id (^)(__kindof ObjectType))block; @end @implementation NSGeneric @@ -395,6 +395,14 @@ void testNullability() { } @end +void testGeneric(NSGeneric<NSString*> *generic) { + NSObject *NSObject_obj; + // Assign from NSObject_obj to __kindof NSString*. + [generic test:NSObject_obj]; // expected-warning{{incompatible pointer types sending 'NSObject *' to parameter of type '__kindof NSString *'}} + NSString *NSString_str; + [generic test:NSString_str]; +} + // Check that clang doesn't crash when a type parameter is illegal. @interface Array1<T> : NSObject @end diff --git a/clang/test/SemaObjC/parameterized_classes_subst.m b/clang/test/SemaObjC/parameterized_classes_subst.m index f90ee909359..da2d56f11bc 100644 --- a/clang/test/SemaObjC/parameterized_classes_subst.m +++ b/clang/test/SemaObjC/parameterized_classes_subst.m @@ -426,3 +426,36 @@ void test_ternary_operator(NSArray<NSString *> *stringArray, // warning about likely protocol/class name typos. // -------------------------------------------------------------------------- typedef NSArray<NSObject> ArrayOfNSObjectWarning; // expected-warning{{parameterized class 'NSArray' already conforms to the protocols listed; did you forget a '*'?}} + +// rdar://25060179 +@interface MyMutableDictionary<KeyType, ObjectType> : NSObject +- (void)setObject:(ObjectType)obj forKeyedSubscript:(KeyType <NSCopying>)key; // expected-note{{passing argument to parameter 'obj' here}} \ + // expected-note{{passing argument to parameter 'key' here}} +@end + +void bar(MyMutableDictionary<NSString *, NSString *> *stringsByString, + NSNumber *n1, NSNumber *n2) { + // We warn here when the key types do not match. + stringsByString[n1] = n2; // expected-warning{{incompatible pointer types sending 'NSNumber *' to parameter of type 'NSString *'}} \ + // expected-warning{{incompatible pointer types sending 'NSNumber *' to parameter of type 'NSString<NSCopying> *'}} +} + +@interface MyTest<K, V> : NSObject <NSCopying> +- (V)test:(K)key; +- (V)test2:(K)key; // expected-note{{previous definition is here}} +- (void)mapUsingBlock:(id (^)(V))block; +- (void)mapUsingBlock2:(id (^)(V))block; // expected-note{{previous definition is here}} +@end + +@implementation MyTest +- (id)test:(id)key { + return key; +} +- (int)test2:(id)key{ // expected-warning{{conflicting return type in implementation}} + return 0; +} +- (void)mapUsingBlock:(id (^)(id))block { +} +- (void)mapUsingBlock2:(id)block { // expected-warning{{conflicting parameter types in implementation}} +} +@end |

