Skip to content
Snippets Groups Projects
Commit 75f24133 authored by Fariborz Jahanian's avatar Fariborz Jahanian
Browse files

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


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@211324 91177308-0d34-0410-b5e6-96231b3b80d8
parent d8a63093
No related branches found
No related tags found
No related merge requests found
...@@ -5491,6 +5491,8 @@ def err_typecheck_missing_return_type_incompatible : Error< ...@@ -5491,6 +5491,8 @@ def err_typecheck_missing_return_type_incompatible : Error<
"return type must match previous return type}0,1 when %select{block " "return type must match previous return type}0,1 when %select{block "
"literal|lambda expression}2 has unspecified explicit return type">; "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< def warn_incompatible_qualified_id : Warning<
"%select{%diff{assigning to $ from incompatible type $|" "%select{%diff{assigning to $ from incompatible type $|"
"assigning to type from incompatible type}0,1" "assigning to type from incompatible type}0,1"
......
...@@ -10832,6 +10832,8 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy, ...@@ -10832,6 +10832,8 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy,
ConversionFixItGenerator ConvHints; ConversionFixItGenerator ConvHints;
bool MayHaveConvFixit = false; bool MayHaveConvFixit = false;
bool MayHaveFunctionDiff = false; bool MayHaveFunctionDiff = false;
const ObjCInterfaceDecl *IFace = nullptr;
const ObjCProtocolDecl *PDecl = nullptr;
   
switch (ConvTy) { switch (ConvTy) {
case Compatible: case Compatible:
...@@ -10913,11 +10915,32 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy, ...@@ -10913,11 +10915,32 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy,
case IncompatibleBlockPointer: case IncompatibleBlockPointer:
DiagKind = diag::err_typecheck_convert_incompatible_block_pointer; DiagKind = diag::err_typecheck_convert_incompatible_block_pointer;
break; break;
case IncompatibleObjCQualifiedId: case IncompatibleObjCQualifiedId: {
// FIXME: Diagnose the problem in ObjCQualifiedIdTypesAreCompatible, since if (SrcType->isObjCQualifiedIdType()) {
// it can give a more specific diagnostic. 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; DiagKind = diag::warn_incompatible_qualified_id;
break; break;
}
case IncompatibleVectors: case IncompatibleVectors:
DiagKind = diag::warn_incompatible_vectors; DiagKind = diag::warn_incompatible_vectors;
break; break;
...@@ -10975,7 +10998,11 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy, ...@@ -10975,7 +10998,11 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy,
HandleFunctionTypeMismatch(FDiag, SecondType, FirstType); HandleFunctionTypeMismatch(FDiag, SecondType, FirstType);
   
Diag(Loc, FDiag); 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) if (SecondType == Context.OverloadTy)
NoteAllOverloadCandidates(OverloadExpr::find(SrcExpr).Expression, NoteAllOverloadCandidates(OverloadExpr::find(SrcExpr).Expression,
FirstType); FirstType);
......
...@@ -35,3 +35,20 @@ void foo(void) ...@@ -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. // 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 *'}} [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 *'}}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment