Skip to content

Commit 02c2ab3

Browse files
committedOct 9, 2019
[ObjC generics] Fix not inheriting type bounds in categories/extensions.
When a category/extension doesn't repeat a type bound, corresponding type parameter is substituted with `id` when used as a type argument. As a result, in the added test case it was causing errors like > type argument 'T' (aka 'id') does not satisfy the bound ('id<NSCopying>') of type parameter 'T' We are already checking that type parameters should be consistent everywhere (see `checkTypeParamListConsistency`) and update `ObjCTypeParamDecl` to have correct underlying type. And when we use the type parameter as a method return type or a method parameter type, it is substituted to the bounded type. But when we use the type parameter as a type argument, we check `ObjCTypeParamType` that ignores the updated underlying type and remains `id`. Fix by desugaring `ObjCTypeParamType` to the underlying type, the same way we are doing with `TypedefType`. rdar://problem/54329242 Reviewers: erik.pilkington, ahatanak Reviewed By: erik.pilkington Subscribers: jkorous, dexonsmith, ributzka, cfe-commits Differential Revision: https://reviews.llvm.org/D66696 llvm-svn: 374202
1 parent 87aa9c9 commit 02c2ab3

File tree

3 files changed

+19
-1
lines changed

3 files changed

+19
-1
lines changed
 

‎clang/include/clang/AST/Type.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -5569,7 +5569,7 @@ class ObjCTypeParamType : public Type,
55695569

55705570
public:
55715571
bool isSugared() const { return true; }
5572-
QualType desugar() const { return getCanonicalTypeInternal(); }
5572+
QualType desugar() const;
55735573

55745574
static bool classof(const Type *T) {
55755575
return T->getTypeClass() == ObjCTypeParam;

‎clang/lib/AST/Type.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -663,6 +663,10 @@ ObjCTypeParamType::ObjCTypeParamType(const ObjCTypeParamDecl *D,
663663
initialize(protocols);
664664
}
665665

666+
QualType ObjCTypeParamType::desugar() const {
667+
return getDecl()->getUnderlyingType();
668+
}
669+
666670
ObjCObjectType::ObjCObjectType(QualType Canonical, QualType Base,
667671
ArrayRef<QualType> typeArgs,
668672
ArrayRef<ObjCProtocolDecl *> protocols,

‎clang/test/SemaObjC/parameterized_classes_subst.m

+14
Original file line numberDiff line numberDiff line change
@@ -467,3 +467,17 @@ - (void)mapUsingBlock:(id (^)(id))block {
467467
- (void)mapUsingBlock2:(id)block { // expected-warning{{conflicting parameter types in implementation}}
468468
}
469469
@end
470+
471+
// --------------------------------------------------------------------------
472+
// Use a type parameter as a type argument.
473+
// --------------------------------------------------------------------------
474+
// Type bounds in a category/extension are omitted. rdar://problem/54329242
475+
@interface ParameterizedContainer<T : id<NSCopying>>
476+
- (ParameterizedContainer<T> *)inInterface;
477+
@end
478+
@interface ParameterizedContainer<T> (Cat)
479+
- (ParameterizedContainer<T> *)inCategory;
480+
@end
481+
@interface ParameterizedContainer<U> ()
482+
- (ParameterizedContainer<U> *)inExtension;
483+
@end

0 commit comments

Comments
 (0)
Please sign in to comment.