if (result != Incompatible && RHS.get()->getType() != LHSType) {
QualType Ty = LHSType.getNonLValueExprType(Context);
Expr *E = RHS.get();
- if (getLangOpts().ObjCAutoRefCount)
- CheckObjCARCConversion(SourceRange(), Ty, E, CCK_ImplicitConversion,
- Diagnose, DiagnoseCFAudited);
+
+ // Check for various Objective-C errors. If we are not reporting
+ // diagnostics and just checking for errors, e.g., during overload
+ // resolution, return Incompatible to indicate the failure.
+ if (getLangOpts().ObjCAutoRefCount &&
+ CheckObjCARCConversion(SourceRange(), Ty, E, CCK_ImplicitConversion,
+ Diagnose, DiagnoseCFAudited) != ACR_okay) {
+ if (!Diagnose)
+ return Incompatible;
+ }
if (getLangOpts().ObjC1 &&
(CheckObjCBridgeRelatedConversions(E->getLocStart(), LHSType,
E->getType(), E, Diagnose) ||
ConversionToObjCStringLiteralCheck(LHSType, E, Diagnose))) {
+ if (!Diagnose)
+ return Incompatible;
+ // Replace the expression with a corrected version and continue so we
+ // can find further errors.
RHS = E;
return Compatible;
}
StringLiteral *SL = dyn_cast<StringLiteral>(SrcExpr);
if (!SL || !SL->isAscii())
return false;
- if (Diagnose)
+ if (Diagnose) {
Diag(SL->getLocStart(), diag::err_missing_atsign_prefix)
<< FixItHint::CreateInsertion(SL->getLocStart(), "@");
- Exp = BuildObjCStringLiteral(SL->getLocStart(), SL).get();
+ Exp = BuildObjCStringLiteral(SL->getLocStart(), SL).get();
+ }
return true;
}
return;
QualType castExprType = castExpr->getType();
+ // Defer emitting a diagnostic for bridge-related casts; that will be
+ // handled by CheckObjCBridgeRelatedConversions.
TypedefNameDecl *TDNDecl = nullptr;
if ((castACTC == ACTC_coreFoundation && exprACTC == ACTC_retainable &&
ObjCBridgeRelatedAttrFromType(castType, TDNDecl)) ||
<< FixItHint::CreateInsertion(SrcExprEndLoc, "]");
Diag(RelatedClass->getLocStart(), diag::note_declared_at);
Diag(TDNDecl->getLocStart(), diag::note_declared_at);
- }
- QualType receiverType = Context.getObjCInterfaceType(RelatedClass);
- // Argument.
- Expr *args[] = { SrcExpr };
- ExprResult msg = BuildClassMessageImplicit(receiverType, false,
+ QualType receiverType = Context.getObjCInterfaceType(RelatedClass);
+ // Argument.
+ Expr *args[] = { SrcExpr };
+ ExprResult msg = BuildClassMessageImplicit(receiverType, false,
ClassMethod->getLocation(),
ClassMethod->getSelector(), ClassMethod,
MultiExprArg(args, 1));
- SrcExpr = msg.get();
+ SrcExpr = msg.get();
+ }
return true;
}
}
}
Diag(RelatedClass->getLocStart(), diag::note_declared_at);
Diag(TDNDecl->getLocStart(), diag::note_declared_at);
- }
- ExprResult msg =
- BuildInstanceMessageImplicit(SrcExpr, SrcType,
- InstanceMethod->getLocation(),
- InstanceMethod->getSelector(),
- InstanceMethod, None);
- SrcExpr = msg.get();
+ ExprResult msg =
+ BuildInstanceMessageImplicit(SrcExpr, SrcType,
+ InstanceMethod->getLocation(),
+ InstanceMethod->getSelector(),
+ InstanceMethod, None);
+ SrcExpr = msg.get();
+ }
return true;
}
}
ARCConversionTypeClass exprACTC = classifyTypeForARCConversion(castExprType);
ARCConversionTypeClass castACTC = classifyTypeForARCConversion(effCastType);
if (exprACTC == castACTC) {
- // check for viablity and report error if casting an rvalue to a
+ // Check for viability and report error if casting an rvalue to a
// life-time qualifier.
- if (Diagnose && castACTC == ACTC_retainable &&
+ if (castACTC == ACTC_retainable &&
(CCK == CCK_CStyleCast || CCK == CCK_OtherCast) &&
castType != castExprType) {
const Type *DT = castType.getTypePtr();
QDT = AT->desugar();
if (QDT != castType &&
QDT.getObjCLifetime() != Qualifiers::OCL_None) {
- SourceLocation loc =
- (castRange.isValid() ? castRange.getBegin()
- : castExpr->getExprLoc());
- Diag(loc, diag::err_arc_nolifetime_behavior);
+ if (Diagnose) {
+ SourceLocation loc = (castRange.isValid() ? castRange.getBegin()
+ : castExpr->getExprLoc());
+ Diag(loc, diag::err_arc_nolifetime_behavior);
+ }
+ return ACR_error;
}
}
return ACR_okay;
CCK != CCK_ImplicitConversion)
return ACR_unbridged;
- // Do not issue bridge cast" diagnostic when implicit casting a cstring
- // to 'NSString *'. Let caller issue a normal mismatched diagnostic with
- // suitable fix-it.
+ // Issue a diagnostic about a missing @-sign when implicit casting a cstring
+ // to 'NSString *', instead of falling through to report a "bridge cast"
+ // diagnostic.
if (castACTC == ACTC_retainable && exprACTC == ACTC_none &&
ConversionToObjCStringLiteralCheck(castType, castExpr, Diagnose))
- return ACR_okay;
+ return ACR_error;
// Do not issue "bridge cast" diagnostic when implicit casting
// a retainable object to a CF type parameter belonging to an audited
// CF API function. Let caller issue a normal type mismatched diagnostic
// instead.
- if (Diagnose &&
- (!DiagnoseCFAudited || exprACTC != ACTC_retainable ||
- castACTC != ACTC_coreFoundation))
- if (!(exprACTC == ACTC_voidPtr && castACTC == ACTC_retainable &&
- (Opc == BO_NE || Opc == BO_EQ)))
+ if ((!DiagnoseCFAudited || exprACTC != ACTC_retainable ||
+ castACTC != ACTC_coreFoundation) &&
+ !(exprACTC == ACTC_voidPtr && castACTC == ACTC_retainable &&
+ (Opc == BO_NE || Opc == BO_EQ))) {
+ if (Diagnose)
diagnoseObjCARCConversion(*this, castRange, castType, castACTC, castExpr,
castExpr, exprACTC, CCK);
+ return ACR_error;
+ }
return ACR_okay;
}
// in overload resolution in ObjC.
struct Type1 { int a; };
+typedef const __attribute__((objc_bridge(id))) void * CFTypeRef;
@interface Iface1 @end
@interface NeverCalled
- (void) test:(struct Type1 *)arg;
+- (void) test2:(CFTypeRef)arg;
@end
@interface TakesIface1
- (void) test:(Iface1 *)arg;
+- (void) test2:(Iface1 *)arg;
@end
// PR26085, rdar://problem/24111333
void testTakesIface1(id x, Iface1 *arg) {
// This should resolve silently to `TakesIface1`.
[x test:arg];
+ [x test2:arg];
}
@class NSString;
[x testStr:"someStringLiteral"];
}
-typedef const void *CFTypeRef;
id CreateSomething();
-@interface NeverCalledv3
-- (void) testCFTypeRef:(struct Type1 *)arg;
-@end
-
@interface TakesCFTypeRef
- (void) testCFTypeRef:(CFTypeRef)arg;
@end
+@interface NeverCalledv3
+- (void) testCFTypeRef:(struct Type1 *)arg;
+@end
+
// Not called out explicitly by PR26085, but related.
void testTakesCFTypeRef(id x) {
// Overload resolution should occur silently, select the CFTypeRef overload,