diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 35 |
1 files changed, 31 insertions, 4 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 58a0c76769f..2654c390ccf 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -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); |