From 98e0aeb587cf5e3e6953ebadcbaab5ec33fb51e4 Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Mon, 9 Dec 2013 22:04:26 +0000 Subject: [PATCH] Objective-C: Improve on various diagnostics related to use of objc_bridge_related attribute. // rdar://15499111 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@196828 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/DiagnosticSemaKinds.td | 19 +-- lib/Sema/SemaExprObjC.cpp | 152 ++++++++++-------- .../arc-objcbridge-related-attribute.m | 52 ++---- ...heck-objcbridge-related-attribute-lookup.m | 12 +- test/SemaObjC/objcbridge-related-attribute.m | 20 +-- .../objcbridge-related-attribute.mm | 12 +- 6 files changed, 123 insertions(+), 144 deletions(-) diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index cf75c868f4..0823b5dcd6 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -2468,20 +2468,15 @@ def warn_objc_invalid_bridge_to_cf : Warning< // objc_bridge_related attribute diagnostics. def err_objc_bridged_related_invalid_class : Error< - "could not find ObjectiveC class %0 to convert %1 to %2">; + "could not find Objective-C class %0 to convert %1 to %2">; def err_objc_bridged_related_invalid_class_name : Error< - "%0 must be name of an ObjectiveC class to be able to convert %1 to %2">; -def err_objc_bridged_related_class_method : Error< - "class method %0 for conversion of CF type %1 to an " - "ObjectiveC object of type %2 not found">; -def err_objc_bridged_related_instance_method : Error< - "instance method %0 for conversion of an ObjectiveC type %1 to a CF " - "object of type %2 not found">; + "%0 must be name of an Objective-C class to be able to convert %1 to %2">; + def err_objc_bridged_related_unknown_method : Error< + "you can't convert %0 to %1, without using an existing " + "%select{class|instance}2 method for this conversion">; def err_objc_bridged_related_known_method : Error< - "%0 must be explicitly converted to %1, use %2 method for this conversion">; -def err_objc_bridged_related_unknown_method : Error< - "%0 must be explicitly converted to %1, define and then use " - "%select{a singular class|an instance}3 method in %2 for this conversion">; + "%0 must be explicitly converted to %1; use %select{%objcclass2|%objcinstance2}3 " + "method for this conversion">; // Function Parameter Semantic Analysis. def err_param_with_void_type : Error<"argument may not have 'void' type">; diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp index 3e547fdebf..96f2456f9d 100644 --- a/lib/Sema/SemaExprObjC.cpp +++ b/lib/Sema/SemaExprObjC.cpp @@ -3084,6 +3084,32 @@ static void addFixitForObjCARCConversion(Sema &S, } } +template +static inline T *getObjCBridgeAttr(const TypedefType *TD) { + TypedefNameDecl *TDNDecl = TD->getDecl(); + QualType QT = TDNDecl->getUnderlyingType(); + if (QT->isPointerType()) { + QT = QT->getPointeeType(); + if (const RecordType *RT = QT->getAs()) + if (RecordDecl *RD = RT->getDecl()) + if (RD->hasAttr()) + return RD->getAttr(); + } + return 0; +} + +static ObjCBridgeRelatedAttr *ObjCBridgeRelatedAttrFromType(QualType T, + TypedefNameDecl *&TDNDecl) { + while (const TypedefType *TD = dyn_cast(T.getTypePtr())) { + TDNDecl = TD->getDecl(); + if (ObjCBridgeRelatedAttr *ObjCBAttr = + getObjCBridgeAttr(TD)) + return ObjCBAttr; + T = TDNDecl->getUnderlyingType(); + } + return 0; +} + static void diagnoseObjCARCConversion(Sema &S, SourceRange castRange, QualType castType, ARCConversionTypeClass castACTC, @@ -3098,6 +3124,12 @@ diagnoseObjCARCConversion(Sema &S, SourceRange castRange, return; QualType castExprType = castExpr->getType(); + TypedefNameDecl *TDNDecl = 0; + if ((castACTC == ACTC_coreFoundation && exprACTC == ACTC_retainable && + ObjCBridgeRelatedAttrFromType(castType, TDNDecl)) || + (exprACTC == ACTC_coreFoundation && castACTC == ACTC_retainable && + ObjCBridgeRelatedAttrFromType(castExprType, TDNDecl))) + return; unsigned srcKind = 0; switch (exprACTC) { @@ -3204,20 +3236,6 @@ diagnoseObjCARCConversion(Sema &S, SourceRange castRange, << castRange << castExpr->getSourceRange(); } -template -static inline T *getObjCBridgeAttr(const TypedefType *TD) { - TypedefNameDecl *TDNDecl = TD->getDecl(); - QualType QT = TDNDecl->getUnderlyingType(); - if (QT->isPointerType()) { - QT = QT->getPointeeType(); - if (const RecordType *RT = QT->getAs()) - if (RecordDecl *RD = RT->getDecl()) - if (RD->hasAttr()) - return RD->getAttr(); - } - return 0; -} - template static bool CheckObjCBridgeNSCast(Sema &S, QualType castType, Expr *castExpr) { QualType T = castExpr->getType(); @@ -3350,65 +3368,61 @@ bool Sema::checkObjCBridgeRelatedComponents(SourceLocation Loc, TypedefNameDecl *&TDNDecl, bool CfToNs) { QualType T = CfToNs ? SrcType : DestType; - while (const TypedefType *TD = dyn_cast(T.getTypePtr())) { - TDNDecl = TD->getDecl(); - if (ObjCBridgeRelatedAttr *ObjCBAttr = - getObjCBridgeAttr(TD)) { - IdentifierInfo *RCId = ObjCBAttr->getRelatedClass(); - IdentifierInfo *CMId = ObjCBAttr->getClassMethod(); - IdentifierInfo *IMId = ObjCBAttr->getInstanceMethod(); - if (!RCId) - return false; - NamedDecl *Target = 0; - // Check for an existing type with this name. - LookupResult R(*this, DeclarationName(RCId), SourceLocation(), - Sema::LookupOrdinaryName); - if (!LookupName(R, TUScope)) { - Diag(Loc, diag::err_objc_bridged_related_invalid_class) << RCId + ObjCBridgeRelatedAttr *ObjCBAttr = ObjCBridgeRelatedAttrFromType(T, TDNDecl); + if (!ObjCBAttr) + return false; + + IdentifierInfo *RCId = ObjCBAttr->getRelatedClass(); + IdentifierInfo *CMId = ObjCBAttr->getClassMethod(); + IdentifierInfo *IMId = ObjCBAttr->getInstanceMethod(); + if (!RCId) + return false; + NamedDecl *Target = 0; + // Check for an existing type with this name. + LookupResult R(*this, DeclarationName(RCId), SourceLocation(), + Sema::LookupOrdinaryName); + if (!LookupName(R, TUScope)) { + Diag(Loc, diag::err_objc_bridged_related_invalid_class) << RCId << SrcType << DestType; - Diag(TDNDecl->getLocStart(), diag::note_declared_at); - return false; - } - Target = R.getFoundDecl(); - if (Target && isa(Target)) - RelatedClass = cast(Target); - else { - Diag(Loc, diag::err_objc_bridged_related_invalid_class_name) << RCId + Diag(TDNDecl->getLocStart(), diag::note_declared_at); + return false; + } + Target = R.getFoundDecl(); + if (Target && isa(Target)) + RelatedClass = cast(Target); + else { + Diag(Loc, diag::err_objc_bridged_related_invalid_class_name) << RCId << SrcType << DestType; - Diag(TDNDecl->getLocStart(), diag::note_declared_at); - if (Target) - Diag(Target->getLocStart(), diag::note_declared_at); - return false; - } + Diag(TDNDecl->getLocStart(), diag::note_declared_at); + if (Target) + Diag(Target->getLocStart(), diag::note_declared_at); + return false; + } - // Check for an existing class method with the given selector name. - if (CfToNs && CMId) { - Selector Sel = Context.Selectors.getUnarySelector(CMId); - ClassMethod = RelatedClass->lookupMethod(Sel, false); - if (!ClassMethod) { - Diag(Loc, diag::err_objc_bridged_related_class_method) - << Sel << SrcType << DestType; - Diag(TDNDecl->getLocStart(), diag::note_declared_at); - return false; - } - } + // Check for an existing class method with the given selector name. + if (CfToNs && CMId) { + Selector Sel = Context.Selectors.getUnarySelector(CMId); + ClassMethod = RelatedClass->lookupMethod(Sel, false); + if (!ClassMethod) { + Diag(Loc, diag::err_objc_bridged_related_known_method) + << SrcType << DestType << Sel << 0; + Diag(TDNDecl->getLocStart(), diag::note_declared_at); + return false; + } + } - // Check for an existing instance method with the given selector name. - if (!CfToNs && IMId) { - Selector Sel = Context.Selectors.getNullarySelector(IMId); - InstanceMethod = RelatedClass->lookupMethod(Sel, true); - if (!InstanceMethod) { - Diag(Loc, diag::err_objc_bridged_related_instance_method) - << Sel << SrcType << DestType; - Diag(TDNDecl->getLocStart(), diag::note_declared_at); - return false; - } - } - return true; + // Check for an existing instance method with the given selector name. + if (!CfToNs && IMId) { + Selector Sel = Context.Selectors.getNullarySelector(IMId); + InstanceMethod = RelatedClass->lookupMethod(Sel, true); + if (!InstanceMethod) { + Diag(Loc, diag::err_objc_bridged_related_known_method) + << SrcType << DestType << Sel << 1; + Diag(TDNDecl->getLocStart(), diag::note_declared_at); + return false; } - T = TDNDecl->getUnderlyingType(); } - return false; + return true; } bool @@ -3436,7 +3450,7 @@ Sema::CheckObjCBridgeRelatedConversions(SourceLocation Loc, << SrcType << DestType << ClassMethod->getSelector() << 0; else Diag(Loc, diag::err_objc_bridged_related_unknown_method) - << SrcType << DestType << RelatedClass->getName() << 0; + << SrcType << DestType << 0; Diag(RelatedClass->getLocStart(), diag::note_declared_at); Diag(TDNDecl->getLocStart(), diag::note_declared_at); } @@ -3447,7 +3461,7 @@ Sema::CheckObjCBridgeRelatedConversions(SourceLocation Loc, << SrcType << DestType << InstanceMethod->getSelector() << 1; else Diag(Loc, diag::err_objc_bridged_related_unknown_method) - << SrcType << DestType << RelatedClass->getName() << 1; + << SrcType << DestType << 1; Diag(RelatedClass->getLocStart(), diag::note_declared_at); Diag(TDNDecl->getLocStart(), diag::note_declared_at); } diff --git a/test/SemaObjC/arc-objcbridge-related-attribute.m b/test/SemaObjC/arc-objcbridge-related-attribute.m index c6bdb27b62..d78ee4dc4e 100644 --- a/test/SemaObjC/arc-objcbridge-related-attribute.m +++ b/test/SemaObjC/arc-objcbridge-related-attribute.m @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -x objective-c -verify -fobjc-arc -Wno-objc-root-class %s +// RUN: %clang_cc1 -fsyntax-only -x objective-c -fobjc-arc -verify -Wno-objc-root-class %s // rdar://15499111 typedef struct __attribute__((objc_bridge_related(NSColor,colorWithCGColor:,CGColor))) CGColor *CGColorRef; // expected-note 5 {{declared here}} @@ -19,53 +19,23 @@ typedef struct __attribute__((objc_bridge_related(NSColor,,))) CGColor2 *CGColor void foo(NSColor*); NSColor * Test1(NSTextField *textField, CGColorRef newColor) { - foo(newColor); // expected-error {{'CGColorRef' (aka 'struct CGColor *') must be explicitly converted to 'NSColor *', use 'colorWithCGColor:' method for this conversion}} \ - // expected-error {{implicit conversion of C pointer type 'CGColorRef' (aka 'struct CGColor *') to Objective-C pointer type 'NSColor *' requires a bridged cast}} \ - // expected-note {{use __bridge to convert directly (no change in ownership)}} \ - // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CGColorRef' (aka 'struct CGColor *') into ARC}} - textField.backgroundColor = newColor; // expected-error {{'CGColorRef' (aka 'struct CGColor *') must be explicitly converted to 'NSColor *__strong', use 'colorWithCGColor:' method for this conversion}} \ - // expected-error {{implicit conversion of C pointer type 'CGColorRef' (aka 'struct CGColor *') to Objective-C pointer type 'NSColor *' requires a bridged cast}} \ - // expected-note {{use __bridge to convert directly (no change in ownership)}} \ - // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CGColorRef' (aka 'struct CGColor *') into ARC}} - return newColor; // expected-error {{'CGColorRef' (aka 'struct CGColor *') must be explicitly converted to 'NSColor *', use 'colorWithCGColor:' method for this conversion}} \ - // expected-error {{implicit conversion of C pointer type 'CGColorRef' (aka 'struct CGColor *') to Objective-C pointer type 'NSColor *' requires a bridged cast}} \ - // expected-note {{use __bridge to convert directly (no change in ownership)}} \ - // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CGColorRef' (aka 'struct CGColor *') into ARC}} + foo(newColor); // expected-error {{'CGColorRef' (aka 'struct CGColor *') must be explicitly converted to 'NSColor *'; use '+colorWithCGColor:' method for this conversion}} + textField.backgroundColor = newColor; // expected-error {{'CGColorRef' (aka 'struct CGColor *') must be explicitly converted to 'NSColor *__strong'; use '+colorWithCGColor:' method for this conversion}} + return newColor; // expected-error {{'CGColorRef' (aka 'struct CGColor *') must be explicitly converted to 'NSColor *'; use '+colorWithCGColor:' method for this conversion}} } NSColor * Test2(NSTextField *textField, CGColorRef1 newColor) { - foo(newColor); // expected-error {{'CGColorRef1' (aka 'struct CGColor1 *') must be explicitly converted to 'NSColor *', define and then use a singular class method in NSColor for this conversion}} \ - // expected-error {{implicit conversion of C pointer type 'CGColorRef1' (aka 'struct CGColor1 *') to Objective-C pointer type 'NSColor *' requires a bridged cast}} \ - // expected-note {{use __bridge to convert directly (no change in ownership)}} \ - // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CGColorRef1' (aka 'struct CGColor1 *') into ARC}} - textField.backgroundColor = newColor; // expected-error {{'CGColorRef1' (aka 'struct CGColor1 *') must be explicitly converted to 'NSColor *__strong', define and then use a singular class method in NSColor for this conversion}} \ - // expected-error {{implicit conversion of C pointer type 'CGColorRef1' (aka 'struct CGColor1 *') to Objective-C pointer type 'NSColor *' requires a bridged cast}} \ - // expected-note {{use __bridge to convert directly (no change in ownership)}} \ - // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CGColorRef1' (aka 'struct CGColor1 *') into ARC}} - return newColor; // expected-error {{'CGColorRef1' (aka 'struct CGColor1 *') must be explicitly converted to 'NSColor *', define and then use a singular class method in NSColor for this conversion}} \ - // expected-error {{implicit conversion of C pointer type 'CGColorRef1' (aka 'struct CGColor1 *') to Objective-C pointer type 'NSColor *' requires a bridged cast}} \ - // expected-note {{use __bridge to convert directly (no change in ownership)}} \ - // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CGColorRef1' (aka 'struct CGColor1 *') into ARC}} + foo(newColor); // expected-error {{you can't convert 'CGColorRef1' (aka 'struct CGColor1 *') to 'NSColor *', without using an existing class method for this conversion}} + textField.backgroundColor = newColor; // expected-error {{you can't convert 'CGColorRef1' (aka 'struct CGColor1 *') to 'NSColor *__strong', without using an existing class method for this conversion}} + return newColor; // expected-error {{you can't convert 'CGColorRef1' (aka 'struct CGColor1 *') to 'NSColor *', without using an existing class method for this conversion}} } CGColorRef Test3(NSTextField *textField, CGColorRef newColor) { - newColor = textField.backgroundColor; // expected-error {{'NSColor *' must be explicitly converted to 'CGColorRef' (aka 'struct CGColor *'), use 'CGColor' method for this conversion}} \ - // expected-error {{implicit conversion of Objective-C pointer type 'NSColor *' to C pointer type 'CGColorRef' (aka 'struct CGColor *') requires a bridged cast}} \ - // expected-note {{use __bridge to convert directly (no change in ownership)}} \ - // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CGColorRef' (aka 'struct CGColor *')}} - return textField.backgroundColor; // expected-error {{'NSColor *' must be explicitly converted to 'CGColorRef' (aka 'struct CGColor *'), use 'CGColor' method for this conversion}} \ - // expected-error {{implicit conversion of Objective-C pointer type 'NSColor *' to C pointer type 'CGColorRef' (aka 'struct CGColor *') requires a bridged cast}} \ - // expected-note {{use __bridge to convert directly (no change in ownership)}} \ - // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CGColorRef' (aka 'struct CGColor *')}} + newColor = textField.backgroundColor; // expected-error {{'NSColor *' must be explicitly converted to 'CGColorRef' (aka 'struct CGColor *'); use '-CGColor' method for this conversion}} + return textField.backgroundColor; // expected-error {{'NSColor *' must be explicitly converted to 'CGColorRef' (aka 'struct CGColor *'); use '-CGColor' method for this conversion}} } CGColorRef2 Test4(NSTextField *textField, CGColorRef2 newColor) { - newColor = textField.backgroundColor; // expected-error {{'NSColor *' must be explicitly converted to 'CGColorRef2' (aka 'struct CGColor2 *'), define and then use an instance method in NSColor for this conversion}} \ - // expected-error {{implicit conversion of Objective-C pointer type 'NSColor *' to C pointer type 'CGColorRef2' (aka 'struct CGColor2 *') requires a bridged cast}} \ - // expected-note {{use __bridge to convert directly (no change in ownership)}} \ - // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CGColorRef2' (aka 'struct CGColor2 *')}} - return textField.backgroundColor; // expected-error {{'NSColor *' must be explicitly converted to 'CGColorRef2' (aka 'struct CGColor2 *'), define and then use an instance method in NSColor for this conversion}} \ - // expected-error {{implicit conversion of Objective-C pointer type 'NSColor *' to C pointer type 'CGColorRef2' (aka 'struct CGColor2 *') requires a bridged cast}} \ - // expected-note {{use __bridge to convert directly (no change in ownership)}} \ - // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CGColorRef2' (aka 'struct CGColor2 *')}} + newColor = textField.backgroundColor; // expected-error {{you can't convert 'NSColor *' to 'CGColorRef2' (aka 'struct CGColor2 *'), without using an existing instance method for this conversion}} + return textField.backgroundColor; // expected-error {{you can't convert 'NSColor *' to 'CGColorRef2' (aka 'struct CGColor2 *'), without using an existing instance method for this conversion}} } diff --git a/test/SemaObjC/check-objcbridge-related-attribute-lookup.m b/test/SemaObjC/check-objcbridge-related-attribute-lookup.m index 66f56cfed4..39b66bc8e8 100644 --- a/test/SemaObjC/check-objcbridge-related-attribute-lookup.m +++ b/test/SemaObjC/check-objcbridge-related-attribute-lookup.m @@ -20,22 +20,22 @@ typedef struct __attribute__((objc_bridge_related(PNsColor,colorWithCGColor:,CGC typedef int PNsColor; // expected-note 2 {{declared here}} NSColor * Test1(NSTextField *textField, CGColorRef newColor) { - textField.backgroundColor = newColor; // expected-error {{class method 'colorXWithCGColor:' for conversion of CF type 'CGColorRef' (aka 'struct CGColor *') to an ObjectiveC object of type 'NSColor *' not found}} \ + textField.backgroundColor = newColor; // expected-error {{'CGColorRef' (aka 'struct CGColor *') must be explicitly converted to 'NSColor *'; use '+colorXWithCGColor:' method for this conversion}} \ // expected-warning {{incompatible pointer types assigning to 'NSColor *' from 'CGColorRef' (aka 'struct CGColor *')}} - newColor = textField.backgroundColor; // expected-error {{instance method 'CXGColor' for conversion of an ObjectiveC type 'NSColor *' to a CF object of type 'CGColorRef' (aka 'struct CGColor *') not found}} \ + newColor = textField.backgroundColor; // expected-error {{'NSColor *' must be explicitly converted to 'CGColorRef' (aka 'struct CGColor *'); use '-CXGColor' method for this conversion}} \ // expected-warning {{incompatible pointer types assigning to 'CGColorRef' (aka 'struct CGColor *') from 'NSColor *'}} } NSColor * Test2(NSTextField *textField, CGColorRef1 newColor) { - textField.backgroundColor = newColor; // expected-error {{could not find ObjectiveC class 'XNSColor' to convert 'CGColorRef1' (aka 'struct CGColor1 *') to 'NSColor *'}} \ + textField.backgroundColor = newColor; // expected-error {{could not find Objective-C class 'XNSColor' to convert 'CGColorRef1' (aka 'struct CGColor1 *') to 'NSColor *'}} \ // expected-warning {{incompatible pointer types assigning to 'NSColor *' from 'CGColorRef1' (aka 'struct CGColor1 *')}} - newColor = textField.backgroundColor ; // expected-error {{could not find ObjectiveC class 'XNSColor' to convert 'NSColor *' to 'CGColorRef1' (aka 'struct CGColor1 *')}} \ + newColor = textField.backgroundColor ; // expected-error {{could not find Objective-C class 'XNSColor' to convert 'NSColor *' to 'CGColorRef1' (aka 'struct CGColor1 *')}} \ // expected-warning {{incompatible pointer types assigning to 'CGColorRef1' (aka 'struct CGColor1 *') from 'NSColor *'}} } NSColor * Test3(NSTextField *textField, CGColorRef2 newColor) { - textField.backgroundColor = newColor; // expected-error {{'PNsColor' must be name of an ObjectiveC class to be able to convert 'CGColorRef2' (aka 'struct CGColor2 *') to 'NSColor *'}} \ + textField.backgroundColor = newColor; // expected-error {{'PNsColor' must be name of an Objective-C class to be able to convert 'CGColorRef2' (aka 'struct CGColor2 *') to 'NSColor *'}} \ // expected-warning {{incompatible pointer types assigning to 'NSColor *' from 'CGColorRef2' (aka 'struct CGColor2 *')}} - newColor = textField.backgroundColor; // expected-error {{'PNsColor' must be name of an ObjectiveC class to be able to convert 'NSColor *' to 'CGColorRef2' (aka 'struct CGColor2 *')}} \ + newColor = textField.backgroundColor; // expected-error {{'PNsColor' must be name of an Objective-C class to be able to convert 'NSColor *' to 'CGColorRef2' (aka 'struct CGColor2 *')}} \ // expected-warning {{incompatible pointer types assigning to 'CGColorRef2' (aka 'struct CGColor2 *') from 'NSColor *'}} } diff --git a/test/SemaObjC/objcbridge-related-attribute.m b/test/SemaObjC/objcbridge-related-attribute.m index bf6b4e7e35..aa6db6f96e 100644 --- a/test/SemaObjC/objcbridge-related-attribute.m +++ b/test/SemaObjC/objcbridge-related-attribute.m @@ -19,23 +19,23 @@ typedef struct __attribute__((objc_bridge_related(NSColor,,))) CGColor2 *CGColor void foo(NSColor*); NSColor * Test1(NSTextField *textField, CGColorRef newColor) { - foo(newColor); // expected-error {{'CGColorRef' (aka 'struct CGColor *') must be explicitly converted to 'NSColor *', use 'colorWithCGColor:' method for this conversion}} - textField.backgroundColor = newColor; // expected-error {{'CGColorRef' (aka 'struct CGColor *') must be explicitly converted to 'NSColor *', use 'colorWithCGColor:' method for this conversion}} - return newColor; // expected-error {{'CGColorRef' (aka 'struct CGColor *') must be explicitly converted to 'NSColor *', use 'colorWithCGColor:' method for this conversion}} + foo(newColor); // expected-error {{'CGColorRef' (aka 'struct CGColor *') must be explicitly converted to 'NSColor *'; use '+colorWithCGColor:' method for this conversion}} + textField.backgroundColor = newColor; // expected-error {{'CGColorRef' (aka 'struct CGColor *') must be explicitly converted to 'NSColor *'; use '+colorWithCGColor:' method for this conversion}} + return newColor; // expected-error {{'CGColorRef' (aka 'struct CGColor *') must be explicitly converted to 'NSColor *'; use '+colorWithCGColor:' method for this conversion}} } NSColor * Test2(NSTextField *textField, CGColorRef1 newColor) { - foo(newColor); // expected-error {{'CGColorRef1' (aka 'struct CGColor1 *') must be explicitly converted to 'NSColor *', define and then use a singular class method in NSColor for this conversion}} - textField.backgroundColor = newColor; // expected-error {{'CGColorRef1' (aka 'struct CGColor1 *') must be explicitly converted to 'NSColor *', define and then use a singular class method in NSColor for this conversion}} - return newColor; // expected-error {{'CGColorRef1' (aka 'struct CGColor1 *') must be explicitly converted to 'NSColor *', define and then use a singular class method in NSColor for this conversion}} + foo(newColor); // expected-error {{you can't convert 'CGColorRef1' (aka 'struct CGColor1 *') to 'NSColor *', without using an existing class method for this conversion}} + textField.backgroundColor = newColor; // expected-error {{you can't convert 'CGColorRef1' (aka 'struct CGColor1 *') to 'NSColor *', without using an existing class method for this conversion}} + return newColor; // expected-error {{you can't convert 'CGColorRef1' (aka 'struct CGColor1 *') to 'NSColor *', without using an existing class method for this conversion}} } CGColorRef Test3(NSTextField *textField, CGColorRef newColor) { - newColor = textField.backgroundColor; // expected-error {{'NSColor *' must be explicitly converted to 'CGColorRef' (aka 'struct CGColor *'), use 'CGColor' method for this conversion}} - return textField.backgroundColor; // expected-error {{'NSColor *' must be explicitly converted to 'CGColorRef' (aka 'struct CGColor *'), use 'CGColor' method for this conversion}} + newColor = textField.backgroundColor; // expected-error {{'NSColor *' must be explicitly converted to 'CGColorRef' (aka 'struct CGColor *'); use '-CGColor' method for this conversion}} + return textField.backgroundColor; // expected-error {{'NSColor *' must be explicitly converted to 'CGColorRef' (aka 'struct CGColor *'); use '-CGColor' method for this conversion}} } CGColorRef2 Test4(NSTextField *textField, CGColorRef2 newColor) { - newColor = textField.backgroundColor; // expected-error {{'NSColor *' must be explicitly converted to 'CGColorRef2' (aka 'struct CGColor2 *'), define and then use an instance method in NSColor for this conversion}} - return textField.backgroundColor; // expected-error {{'NSColor *' must be explicitly converted to 'CGColorRef2' (aka 'struct CGColor2 *'), define and then use an instance method in NSColor for this conversion}} + newColor = textField.backgroundColor; // expected-error {{you can't convert 'NSColor *' to 'CGColorRef2' (aka 'struct CGColor2 *'), without using an existing instance method for this conversion}} + return textField.backgroundColor; // expected-error {{you can't convert 'NSColor *' to 'CGColorRef2' (aka 'struct CGColor2 *'), without using an existing instance method for this conversion}} } diff --git a/test/SemaObjCXX/objcbridge-related-attribute.mm b/test/SemaObjCXX/objcbridge-related-attribute.mm index 787e94081d..4270b2b8c0 100644 --- a/test/SemaObjCXX/objcbridge-related-attribute.mm +++ b/test/SemaObjCXX/objcbridge-related-attribute.mm @@ -14,18 +14,18 @@ typedef struct __attribute__((objc_bridge_related(NSColor,colorWithCGColor:,CGCo NSColor *Test1(NSColor *nsColor, CGColorRef newColor) { - nsColor = newColor; // expected-error {{'CGColorRef' (aka 'CGColor *') must be explicitly converted to 'NSColor *', use 'colorWithCGColor:' method for this conversion}} - NSColor *ns = newColor; // expected-error {{'CGColorRef' (aka 'CGColor *') must be explicitly converted to 'NSColor *', use 'colorWithCGColor:' method for this conversion}} \ + nsColor = newColor; // expected-error {{'CGColorRef' (aka 'CGColor *') must be explicitly converted to 'NSColor *'; use '+colorWithCGColor:' method for this conversion}} + NSColor *ns = newColor; // expected-error {{'CGColorRef' (aka 'CGColor *') must be explicitly converted to 'NSColor *'; use '+colorWithCGColor:' method for this conversion}} \ // expected-error {{cannot initialize a variable of type 'NSColor *' with an lvalue of type 'CGColorRef' (aka 'CGColor *')}} - return newColor; // expected-error {{'CGColorRef' (aka 'CGColor *') must be explicitly converted to 'NSColor *', use 'colorWithCGColor:' method for this conversion}} \ + return newColor; // expected-error {{'CGColorRef' (aka 'CGColor *') must be explicitly converted to 'NSColor *'; use '+colorWithCGColor:' method for this conversion}} \ // expected-error {{cannot initialize return object of type 'NSColor *' with an lvalue of type 'CGColorRef' (aka 'CGColor *')}} } CGColorRef Test2(NSColor *newColor, CGColorRef cgColor) { - cgColor = newColor; // expected-error {{'NSColor *' must be explicitly converted to 'CGColorRef' (aka 'CGColor *'), use 'CGColor' method for this conversion}} - CGColorRef cg = newColor; // expected-error {{'NSColor *' must be explicitly converted to 'CGColorRef' (aka 'CGColor *'), use 'CGColor' method for this conversion}} \ + cgColor = newColor; // expected-error {{'NSColor *' must be explicitly converted to 'CGColorRef' (aka 'CGColor *'); use '-CGColor' method for this conversion}} + CGColorRef cg = newColor; // expected-error {{'NSColor *' must be explicitly converted to 'CGColorRef' (aka 'CGColor *'); use '-CGColor' method for this conversion}} \ // expected-error {{cannot initialize a variable of type 'CGColorRef' (aka 'CGColor *') with an lvalue of type 'NSColor *'}} - return newColor; // expected-error {{'NSColor *' must be explicitly converted to 'CGColorRef' (aka 'CGColor *'), use 'CGColor' method for this conversion}}\ + return newColor; // expected-error {{'NSColor *' must be explicitly converted to 'CGColorRef' (aka 'CGColor *'); use '-CGColor' method for this conversion}}\ // expected-error {{cannot initialize return object of type 'CGColorRef' (aka 'CGColor *') with an lvalue of type 'NSColor *'}} } -- 2.40.0