forked from OSchip/llvm-project
Objective-C qoi. When Objective-C pointer mismatches with
a qualified-id type because pointer is object of a forward class declaration, include this info in a diagnostic note. // rdar://10751015 llvm-svn: 211324
This commit is contained in:
parent
1b3f344713
commit
d329674028
|
@ -5491,6 +5491,8 @@ def err_typecheck_missing_return_type_incompatible : Error<
|
|||
"return type must match previous return type}0,1 when %select{block "
|
||||
"literal|lambda expression}2 has unspecified explicit return type">;
|
||||
|
||||
def not_incomplete_class_and_qualified_id : Note<
|
||||
"conformance of forward class %0 to protocol %1 can not be confirmed">;
|
||||
def warn_incompatible_qualified_id : Warning<
|
||||
"%select{%diff{assigning to $ from incompatible type $|"
|
||||
"assigning to type from incompatible type}0,1"
|
||||
|
|
|
@ -10832,6 +10832,8 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy,
|
|||
ConversionFixItGenerator ConvHints;
|
||||
bool MayHaveConvFixit = false;
|
||||
bool MayHaveFunctionDiff = false;
|
||||
const ObjCInterfaceDecl *IFace = nullptr;
|
||||
const ObjCProtocolDecl *PDecl = nullptr;
|
||||
|
||||
switch (ConvTy) {
|
||||
case Compatible:
|
||||
|
@ -10913,11 +10915,32 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy,
|
|||
case IncompatibleBlockPointer:
|
||||
DiagKind = diag::err_typecheck_convert_incompatible_block_pointer;
|
||||
break;
|
||||
case IncompatibleObjCQualifiedId:
|
||||
// FIXME: Diagnose the problem in ObjCQualifiedIdTypesAreCompatible, since
|
||||
// it can give a more specific diagnostic.
|
||||
case IncompatibleObjCQualifiedId: {
|
||||
if (SrcType->isObjCQualifiedIdType()) {
|
||||
const ObjCObjectPointerType *srcOPT =
|
||||
SrcType->getAs<ObjCObjectPointerType>();
|
||||
for (auto *srcProto : srcOPT->quals()) {
|
||||
PDecl = srcProto;
|
||||
break;
|
||||
}
|
||||
if (const ObjCInterfaceType *IFaceT =
|
||||
DstType->getAs<ObjCObjectPointerType>()->getInterfaceType())
|
||||
IFace = IFaceT->getDecl();
|
||||
}
|
||||
else if (DstType->isObjCQualifiedIdType()) {
|
||||
const ObjCObjectPointerType *dstOPT =
|
||||
DstType->getAs<ObjCObjectPointerType>();
|
||||
for (auto *dstProto : dstOPT->quals()) {
|
||||
PDecl = dstProto;
|
||||
break;
|
||||
}
|
||||
if (const ObjCInterfaceType *IFaceT =
|
||||
SrcType->getAs<ObjCObjectPointerType>()->getInterfaceType())
|
||||
IFace = IFaceT->getDecl();
|
||||
}
|
||||
DiagKind = diag::warn_incompatible_qualified_id;
|
||||
break;
|
||||
}
|
||||
case IncompatibleVectors:
|
||||
DiagKind = diag::warn_incompatible_vectors;
|
||||
break;
|
||||
|
@ -10975,7 +10998,11 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy,
|
|||
HandleFunctionTypeMismatch(FDiag, SecondType, FirstType);
|
||||
|
||||
Diag(Loc, FDiag);
|
||||
|
||||
if (DiagKind == diag::warn_incompatible_qualified_id &&
|
||||
PDecl && IFace && !IFace->hasDefinition())
|
||||
Diag(IFace->getLocation(), diag::not_incomplete_class_and_qualified_id)
|
||||
<< IFace->getName() << PDecl->getName();
|
||||
|
||||
if (SecondType == Context.OverloadTy)
|
||||
NoteAllOverloadCandidates(OverloadExpr::find(SrcExpr).Expression,
|
||||
FirstType);
|
||||
|
|
|
@ -35,3 +35,20 @@ void foo(void)
|
|||
// Since registerFunc: expects a Derived object as it's second argument, I don't know why this would be legal.
|
||||
[Derived registerFunc: ExternFunc]; // expected-warning{{incompatible pointer types sending 'NSObject *(NSObject *, NSObject *)' to parameter of type 'FuncSignature *'}}
|
||||
}
|
||||
|
||||
// rdar://10751015
|
||||
@protocol NSCopying @end
|
||||
@interface I
|
||||
- (void) Meth : (id <NSCopying>)aKey; // expected-note {{passing argument to parameter 'aKey' here}}
|
||||
@end
|
||||
|
||||
@class ForwarClass; // expected-note 3 {{conformance of forward class ForwarClass to protocol NSCopying can not be confirmed}}
|
||||
|
||||
ForwarClass *Test10751015 (I* pi, ForwarClass *ns_forward) {
|
||||
|
||||
[pi Meth : ns_forward ]; // expected-warning {{sending 'ForwarClass *' to parameter of incompatible type 'id<NSCopying>'}}
|
||||
|
||||
id <NSCopying> id_ns = ns_forward; // expected-warning {{initializing 'id<NSCopying>' with an expression of incompatible type 'ForwarClass *'}}
|
||||
|
||||
return id_ns; // expected-warning {{returning 'id<NSCopying>' from a function with incompatible result type 'ForwarClass *'}}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue