forked from OSchip/llvm-project
[Sema] Suppress diags in overload resolution.
We were emitting diagnostics from our shiny new C-only overload resolution mode. This patch attempts to silence all such diagnostics. This fixes PR26085. Differential Revision: http://reviews.llvm.org/D16159 llvm-svn: 257710
This commit is contained in:
parent
664fd461c2
commit
60bc972575
|
@ -2229,7 +2229,8 @@ public:
|
|||
bool CheckPointerConversion(Expr *From, QualType ToType,
|
||||
CastKind &Kind,
|
||||
CXXCastPath& BasePath,
|
||||
bool IgnoreBaseAccess);
|
||||
bool IgnoreBaseAccess,
|
||||
bool Diagnose = true);
|
||||
bool IsMemberPointerConversion(Expr *From, QualType FromType, QualType ToType,
|
||||
bool InOverloadResolution,
|
||||
QualType &ConvertedType);
|
||||
|
@ -5388,7 +5389,8 @@ public:
|
|||
unsigned AmbigiousBaseConvID,
|
||||
SourceLocation Loc, SourceRange Range,
|
||||
DeclarationName Name,
|
||||
CXXCastPath *BasePath);
|
||||
CXXCastPath *BasePath,
|
||||
bool IgnoreAccess = false);
|
||||
|
||||
std::string getAmbiguousPathsDisplayString(CXXBasePaths &Paths);
|
||||
|
||||
|
@ -7514,14 +7516,15 @@ public:
|
|||
ObjCMethodDecl *&ClassMethod,
|
||||
ObjCMethodDecl *&InstanceMethod,
|
||||
TypedefNameDecl *&TDNDecl,
|
||||
bool CfToNs);
|
||||
|
||||
bool CfToNs, bool Diagnose = true);
|
||||
|
||||
bool CheckObjCBridgeRelatedConversions(SourceLocation Loc,
|
||||
QualType DestType, QualType SrcType,
|
||||
Expr *&SrcExpr);
|
||||
|
||||
bool ConversionToObjCStringLiteralCheck(QualType DstType, Expr *&SrcExpr);
|
||||
|
||||
Expr *&SrcExpr, bool Diagnose = true);
|
||||
|
||||
bool ConversionToObjCStringLiteralCheck(QualType DstType, Expr *&SrcExpr,
|
||||
bool Diagnose = true);
|
||||
|
||||
bool checkInitMethod(ObjCMethodDecl *method, QualType receiverTypeIfCall);
|
||||
|
||||
/// \brief Check whether the given new method is a valid override of the
|
||||
|
@ -8613,6 +8616,7 @@ public:
|
|||
ARCConversionResult CheckObjCARCConversion(SourceRange castRange,
|
||||
QualType castType, Expr *&op,
|
||||
CheckedConversionKind CCK,
|
||||
bool Diagnose = true,
|
||||
bool DiagnoseCFAudited = false,
|
||||
BinaryOperatorKind Opc = BO_PtrMemD
|
||||
);
|
||||
|
|
|
@ -1742,13 +1742,18 @@ void Sema::BuildBasePathArray(const CXXBasePaths &Paths,
|
|||
/// otherwise. Loc is the location where this routine should point to
|
||||
/// if there is an error, and Range is the source range to highlight
|
||||
/// if there is an error.
|
||||
///
|
||||
/// If either InaccessibleBaseID or AmbigiousBaseConvID are 0, then the
|
||||
/// diagnostic for the respective type of error will be suppressed, but the
|
||||
/// check for ill-formed code will still be performed.
|
||||
bool
|
||||
Sema::CheckDerivedToBaseConversion(QualType Derived, QualType Base,
|
||||
unsigned InaccessibleBaseID,
|
||||
unsigned AmbigiousBaseConvID,
|
||||
SourceLocation Loc, SourceRange Range,
|
||||
DeclarationName Name,
|
||||
CXXCastPath *BasePath) {
|
||||
CXXCastPath *BasePath,
|
||||
bool IgnoreAccess) {
|
||||
// First, determine whether the path from Derived to Base is
|
||||
// ambiguous. This is slightly more expensive than checking whether
|
||||
// the Derived to Base conversion exists, because here we need to
|
||||
|
@ -1761,7 +1766,7 @@ Sema::CheckDerivedToBaseConversion(QualType Derived, QualType Base,
|
|||
(void)DerivationOkay;
|
||||
|
||||
if (!Paths.isAmbiguous(Context.getCanonicalType(Base).getUnqualifiedType())) {
|
||||
if (InaccessibleBaseID) {
|
||||
if (!IgnoreAccess) {
|
||||
// Check that the base class can be accessed.
|
||||
switch (CheckBaseClassAccess(Loc, Base, Derived, Paths.front(),
|
||||
InaccessibleBaseID)) {
|
||||
|
@ -1810,12 +1815,10 @@ Sema::CheckDerivedToBaseConversion(QualType Derived, QualType Base,
|
|||
SourceLocation Loc, SourceRange Range,
|
||||
CXXCastPath *BasePath,
|
||||
bool IgnoreAccess) {
|
||||
return CheckDerivedToBaseConversion(Derived, Base,
|
||||
IgnoreAccess ? 0
|
||||
: diag::err_upcast_to_inaccessible_base,
|
||||
diag::err_ambiguous_derived_to_base_conv,
|
||||
Loc, Range, DeclarationName(),
|
||||
BasePath);
|
||||
return CheckDerivedToBaseConversion(
|
||||
Derived, Base, diag::err_upcast_to_inaccessible_base,
|
||||
diag::err_ambiguous_derived_to_base_conv, Loc, Range, DeclarationName(),
|
||||
BasePath, IgnoreAccess);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -7354,11 +7354,14 @@ Sema::CheckSingleAssignmentConstraints(QualType LHSType, ExprResult &CallerRHS,
|
|||
LHSType->isBlockPointerType()) &&
|
||||
RHS.get()->isNullPointerConstant(Context,
|
||||
Expr::NPC_ValueDependentIsNull)) {
|
||||
CastKind Kind;
|
||||
CXXCastPath Path;
|
||||
CheckPointerConversion(RHS.get(), LHSType, Kind, Path, false);
|
||||
if (ConvertRHS)
|
||||
RHS = ImpCastExprToType(RHS.get(), LHSType, Kind, VK_RValue, &Path);
|
||||
if (Diagnose || ConvertRHS) {
|
||||
CastKind Kind;
|
||||
CXXCastPath Path;
|
||||
CheckPointerConversion(RHS.get(), LHSType, Kind, Path,
|
||||
/*IgnoreBaseAccess=*/false, Diagnose);
|
||||
if (ConvertRHS)
|
||||
RHS = ImpCastExprToType(RHS.get(), LHSType, Kind, VK_RValue, &Path);
|
||||
}
|
||||
return Compatible;
|
||||
}
|
||||
|
||||
|
@ -7376,8 +7379,8 @@ Sema::CheckSingleAssignmentConstraints(QualType LHSType, ExprResult &CallerRHS,
|
|||
}
|
||||
|
||||
Expr *PRE = RHS.get()->IgnoreParenCasts();
|
||||
if (ObjCProtocolExpr *OPE = dyn_cast<ObjCProtocolExpr>(PRE)) {
|
||||
ObjCProtocolDecl *PDecl = OPE->getProtocol();
|
||||
if (Diagnose && isa<ObjCProtocolExpr>(PRE)) {
|
||||
ObjCProtocolDecl *PDecl = cast<ObjCProtocolExpr>(PRE)->getProtocol();
|
||||
if (PDecl && !PDecl->hasDefinition()) {
|
||||
Diag(PRE->getExprLoc(), diag::warn_atprotocol_protocol) << PDecl->getName();
|
||||
Diag(PDecl->getLocation(), diag::note_entity_declared_at) << PDecl;
|
||||
|
@ -7399,11 +7402,11 @@ Sema::CheckSingleAssignmentConstraints(QualType LHSType, ExprResult &CallerRHS,
|
|||
Expr *E = RHS.get();
|
||||
if (getLangOpts().ObjCAutoRefCount)
|
||||
CheckObjCARCConversion(SourceRange(), Ty, E, CCK_ImplicitConversion,
|
||||
DiagnoseCFAudited);
|
||||
Diagnose, DiagnoseCFAudited);
|
||||
if (getLangOpts().ObjC1 &&
|
||||
(CheckObjCBridgeRelatedConversions(E->getLocStart(),
|
||||
LHSType, E->getType(), E) ||
|
||||
ConversionToObjCStringLiteralCheck(LHSType, E))) {
|
||||
(CheckObjCBridgeRelatedConversions(E->getLocStart(), LHSType,
|
||||
E->getType(), E, Diagnose) ||
|
||||
ConversionToObjCStringLiteralCheck(LHSType, E, Diagnose))) {
|
||||
RHS = E;
|
||||
return Compatible;
|
||||
}
|
||||
|
@ -8961,8 +8964,9 @@ QualType Sema::CheckCompareOperands(ExprResult &LHS, ExprResult &RHS,
|
|||
else {
|
||||
Expr *E = RHS.get();
|
||||
if (getLangOpts().ObjCAutoRefCount)
|
||||
CheckObjCARCConversion(SourceRange(), LHSType, E, CCK_ImplicitConversion, false,
|
||||
Opc);
|
||||
CheckObjCARCConversion(SourceRange(), LHSType, E,
|
||||
CCK_ImplicitConversion, /*Diagnose=*/true,
|
||||
/*DiagnoseCFAudited=*/false, Opc);
|
||||
RHS = ImpCastExprToType(E, LHSType,
|
||||
LPT ? CK_BitCast :CK_CPointerToObjCPointerCast);
|
||||
}
|
||||
|
@ -11830,8 +11834,8 @@ ExprResult Sema::ActOnGNUNullExpr(SourceLocation TokenLoc) {
|
|||
return new (Context) GNUNullExpr(Ty, TokenLoc);
|
||||
}
|
||||
|
||||
bool
|
||||
Sema::ConversionToObjCStringLiteralCheck(QualType DstType, Expr *&Exp) {
|
||||
bool Sema::ConversionToObjCStringLiteralCheck(QualType DstType, Expr *&Exp,
|
||||
bool Diagnose) {
|
||||
if (!getLangOpts().ObjC1)
|
||||
return false;
|
||||
|
||||
|
@ -11857,8 +11861,9 @@ Sema::ConversionToObjCStringLiteralCheck(QualType DstType, Expr *&Exp) {
|
|||
StringLiteral *SL = dyn_cast<StringLiteral>(SrcExpr);
|
||||
if (!SL || !SL->isAscii())
|
||||
return false;
|
||||
Diag(SL->getLocStart(), diag::err_missing_atsign_prefix)
|
||||
<< FixItHint::CreateInsertion(SL->getLocStart(), "@");
|
||||
if (Diagnose)
|
||||
Diag(SL->getLocStart(), diag::err_missing_atsign_prefix)
|
||||
<< FixItHint::CreateInsertion(SL->getLocStart(), "@");
|
||||
Exp = BuildObjCStringLiteral(SL->getLocStart(), SL).get();
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -3816,7 +3816,7 @@ bool Sema::checkObjCBridgeRelatedComponents(SourceLocation Loc,
|
|||
ObjCMethodDecl *&ClassMethod,
|
||||
ObjCMethodDecl *&InstanceMethod,
|
||||
TypedefNameDecl *&TDNDecl,
|
||||
bool CfToNs) {
|
||||
bool CfToNs, bool Diagnose) {
|
||||
QualType T = CfToNs ? SrcType : DestType;
|
||||
ObjCBridgeRelatedAttr *ObjCBAttr = ObjCBridgeRelatedAttrFromType(T, TDNDecl);
|
||||
if (!ObjCBAttr)
|
||||
|
@ -3832,20 +3832,24 @@ bool Sema::checkObjCBridgeRelatedComponents(SourceLocation Loc,
|
|||
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);
|
||||
if (Diagnose) {
|
||||
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<ObjCInterfaceDecl>(Target))
|
||||
RelatedClass = cast<ObjCInterfaceDecl>(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);
|
||||
if (Diagnose) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -3854,9 +3858,11 @@ bool Sema::checkObjCBridgeRelatedComponents(SourceLocation Loc,
|
|||
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 << false;
|
||||
Diag(TDNDecl->getLocStart(), diag::note_declared_at);
|
||||
if (Diagnose) {
|
||||
Diag(Loc, diag::err_objc_bridged_related_known_method)
|
||||
<< SrcType << DestType << Sel << false;
|
||||
Diag(TDNDecl->getLocStart(), diag::note_declared_at);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -3866,9 +3872,11 @@ bool Sema::checkObjCBridgeRelatedComponents(SourceLocation Loc,
|
|||
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 << true;
|
||||
Diag(TDNDecl->getLocStart(), diag::note_declared_at);
|
||||
if (Diagnose) {
|
||||
Diag(Loc, diag::err_objc_bridged_related_known_method)
|
||||
<< SrcType << DestType << Sel << true;
|
||||
Diag(TDNDecl->getLocStart(), diag::note_declared_at);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -3878,7 +3886,7 @@ bool Sema::checkObjCBridgeRelatedComponents(SourceLocation Loc,
|
|||
bool
|
||||
Sema::CheckObjCBridgeRelatedConversions(SourceLocation Loc,
|
||||
QualType DestType, QualType SrcType,
|
||||
Expr *&SrcExpr) {
|
||||
Expr *&SrcExpr, bool Diagnose) {
|
||||
ARCConversionTypeClass rhsExprACTC = classifyTypeForARCConversion(SrcType);
|
||||
ARCConversionTypeClass lhsExprACTC = classifyTypeForARCConversion(DestType);
|
||||
bool CfToNs = (rhsExprACTC == ACTC_coreFoundation && lhsExprACTC == ACTC_retainable);
|
||||
|
@ -3891,27 +3899,29 @@ Sema::CheckObjCBridgeRelatedConversions(SourceLocation Loc,
|
|||
ObjCMethodDecl *InstanceMethod = nullptr;
|
||||
TypedefNameDecl *TDNDecl = nullptr;
|
||||
if (!checkObjCBridgeRelatedComponents(Loc, DestType, SrcType, RelatedClass,
|
||||
ClassMethod, InstanceMethod, TDNDecl, CfToNs))
|
||||
ClassMethod, InstanceMethod, TDNDecl,
|
||||
CfToNs, Diagnose))
|
||||
return false;
|
||||
|
||||
if (CfToNs) {
|
||||
// Implicit conversion from CF to ObjC object is needed.
|
||||
if (ClassMethod) {
|
||||
std::string ExpressionString = "[";
|
||||
ExpressionString += RelatedClass->getNameAsString();
|
||||
ExpressionString += " ";
|
||||
ExpressionString += ClassMethod->getSelector().getAsString();
|
||||
SourceLocation SrcExprEndLoc = getLocForEndOfToken(SrcExpr->getLocEnd());
|
||||
// Provide a fixit: [RelatedClass ClassMethod SrcExpr]
|
||||
Diag(Loc, diag::err_objc_bridged_related_known_method)
|
||||
<< SrcType << DestType << ClassMethod->getSelector() << false
|
||||
<< FixItHint::CreateInsertion(SrcExpr->getLocStart(), ExpressionString)
|
||||
<< FixItHint::CreateInsertion(SrcExprEndLoc, "]");
|
||||
Diag(RelatedClass->getLocStart(), diag::note_declared_at);
|
||||
Diag(TDNDecl->getLocStart(), diag::note_declared_at);
|
||||
if (Diagnose) {
|
||||
std::string ExpressionString = "[";
|
||||
ExpressionString += RelatedClass->getNameAsString();
|
||||
ExpressionString += " ";
|
||||
ExpressionString += ClassMethod->getSelector().getAsString();
|
||||
SourceLocation SrcExprEndLoc = getLocForEndOfToken(SrcExpr->getLocEnd());
|
||||
// Provide a fixit: [RelatedClass ClassMethod SrcExpr]
|
||||
Diag(Loc, diag::err_objc_bridged_related_known_method)
|
||||
<< SrcType << DestType << ClassMethod->getSelector() << false
|
||||
<< FixItHint::CreateInsertion(SrcExpr->getLocStart(), ExpressionString)
|
||||
<< FixItHint::CreateInsertion(SrcExprEndLoc, "]");
|
||||
Diag(RelatedClass->getLocStart(), diag::note_declared_at);
|
||||
Diag(TDNDecl->getLocStart(), diag::note_declared_at);
|
||||
}
|
||||
|
||||
QualType receiverType =
|
||||
Context.getObjCInterfaceType(RelatedClass);
|
||||
QualType receiverType = Context.getObjCInterfaceType(RelatedClass);
|
||||
// Argument.
|
||||
Expr *args[] = { SrcExpr };
|
||||
ExprResult msg = BuildClassMessageImplicit(receiverType, false,
|
||||
|
@ -3925,30 +3935,34 @@ Sema::CheckObjCBridgeRelatedConversions(SourceLocation Loc,
|
|||
else {
|
||||
// Implicit conversion from ObjC type to CF object is needed.
|
||||
if (InstanceMethod) {
|
||||
std::string ExpressionString;
|
||||
SourceLocation SrcExprEndLoc = getLocForEndOfToken(SrcExpr->getLocEnd());
|
||||
if (InstanceMethod->isPropertyAccessor())
|
||||
if (const ObjCPropertyDecl *PDecl = InstanceMethod->findPropertyDecl()) {
|
||||
// fixit: ObjectExpr.propertyname when it is aproperty accessor.
|
||||
ExpressionString = ".";
|
||||
ExpressionString += PDecl->getNameAsString();
|
||||
if (Diagnose) {
|
||||
std::string ExpressionString;
|
||||
SourceLocation SrcExprEndLoc =
|
||||
getLocForEndOfToken(SrcExpr->getLocEnd());
|
||||
if (InstanceMethod->isPropertyAccessor())
|
||||
if (const ObjCPropertyDecl *PDecl =
|
||||
InstanceMethod->findPropertyDecl()) {
|
||||
// fixit: ObjectExpr.propertyname when it is aproperty accessor.
|
||||
ExpressionString = ".";
|
||||
ExpressionString += PDecl->getNameAsString();
|
||||
Diag(Loc, diag::err_objc_bridged_related_known_method)
|
||||
<< SrcType << DestType << InstanceMethod->getSelector() << true
|
||||
<< FixItHint::CreateInsertion(SrcExprEndLoc, ExpressionString);
|
||||
}
|
||||
if (ExpressionString.empty()) {
|
||||
// Provide a fixit: [ObjectExpr InstanceMethod]
|
||||
ExpressionString = " ";
|
||||
ExpressionString += InstanceMethod->getSelector().getAsString();
|
||||
ExpressionString += "]";
|
||||
|
||||
Diag(Loc, diag::err_objc_bridged_related_known_method)
|
||||
<< SrcType << DestType << InstanceMethod->getSelector() << true
|
||||
<< FixItHint::CreateInsertion(SrcExprEndLoc, ExpressionString);
|
||||
<< SrcType << DestType << InstanceMethod->getSelector() << true
|
||||
<< FixItHint::CreateInsertion(SrcExpr->getLocStart(), "[")
|
||||
<< FixItHint::CreateInsertion(SrcExprEndLoc, ExpressionString);
|
||||
}
|
||||
if (ExpressionString.empty()) {
|
||||
// Provide a fixit: [ObjectExpr InstanceMethod]
|
||||
ExpressionString = " ";
|
||||
ExpressionString += InstanceMethod->getSelector().getAsString();
|
||||
ExpressionString += "]";
|
||||
|
||||
Diag(Loc, diag::err_objc_bridged_related_known_method)
|
||||
<< SrcType << DestType << InstanceMethod->getSelector() << true
|
||||
<< FixItHint::CreateInsertion(SrcExpr->getLocStart(), "[")
|
||||
<< FixItHint::CreateInsertion(SrcExprEndLoc, ExpressionString);
|
||||
Diag(RelatedClass->getLocStart(), diag::note_declared_at);
|
||||
Diag(TDNDecl->getLocStart(), diag::note_declared_at);
|
||||
}
|
||||
Diag(RelatedClass->getLocStart(), diag::note_declared_at);
|
||||
Diag(TDNDecl->getLocStart(), diag::note_declared_at);
|
||||
|
||||
ExprResult msg =
|
||||
BuildInstanceMessageImplicit(SrcExpr, SrcType,
|
||||
|
@ -3965,6 +3979,7 @@ Sema::CheckObjCBridgeRelatedConversions(SourceLocation Loc,
|
|||
Sema::ARCConversionResult
|
||||
Sema::CheckObjCARCConversion(SourceRange castRange, QualType castType,
|
||||
Expr *&castExpr, CheckedConversionKind CCK,
|
||||
bool Diagnose,
|
||||
bool DiagnoseCFAudited,
|
||||
BinaryOperatorKind Opc) {
|
||||
QualType castExprType = castExpr->getType();
|
||||
|
@ -3980,9 +3995,9 @@ Sema::CheckObjCARCConversion(SourceRange castRange, QualType castType,
|
|||
if (exprACTC == castACTC) {
|
||||
// check for viablity and report error if casting an rvalue to a
|
||||
// life-time qualifier.
|
||||
if ((castACTC == ACTC_retainable) &&
|
||||
if (Diagnose && castACTC == ACTC_retainable &&
|
||||
(CCK == CCK_CStyleCast || CCK == CCK_OtherCast) &&
|
||||
(castType != castExprType)) {
|
||||
castType != castExprType) {
|
||||
const Type *DT = castType.getTypePtr();
|
||||
QualType QDT = castType;
|
||||
// We desugar some types but not others. We ignore those
|
||||
|
@ -4051,19 +4066,20 @@ Sema::CheckObjCARCConversion(SourceRange castRange, QualType castType,
|
|||
// to 'NSString *'. Let caller issue a normal mismatched diagnostic with
|
||||
// suitable fix-it.
|
||||
if (castACTC == ACTC_retainable && exprACTC == ACTC_none &&
|
||||
ConversionToObjCStringLiteralCheck(castType, castExpr))
|
||||
ConversionToObjCStringLiteralCheck(castType, castExpr, Diagnose))
|
||||
return ACR_okay;
|
||||
|
||||
// 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 (!DiagnoseCFAudited || exprACTC != ACTC_retainable ||
|
||||
castACTC != ACTC_coreFoundation)
|
||||
if (Diagnose &&
|
||||
(!DiagnoseCFAudited || exprACTC != ACTC_retainable ||
|
||||
castACTC != ACTC_coreFoundation))
|
||||
if (!(exprACTC == ACTC_voidPtr && castACTC == ACTC_retainable &&
|
||||
(Opc == BO_NE || Opc == BO_EQ)))
|
||||
diagnoseObjCARCConversion(*this, castRange, castType, castACTC,
|
||||
castExpr, castExpr, exprACTC, CCK);
|
||||
diagnoseObjCARCConversion(*this, castRange, castType, castACTC, castExpr,
|
||||
castExpr, exprACTC, CCK);
|
||||
return ACR_okay;
|
||||
}
|
||||
|
||||
|
|
|
@ -2687,15 +2687,16 @@ bool Sema::FunctionParamTypesAreEqual(const FunctionProtoType *OldType,
|
|||
bool Sema::CheckPointerConversion(Expr *From, QualType ToType,
|
||||
CastKind &Kind,
|
||||
CXXCastPath& BasePath,
|
||||
bool IgnoreBaseAccess) {
|
||||
bool IgnoreBaseAccess,
|
||||
bool Diagnose) {
|
||||
QualType FromType = From->getType();
|
||||
bool IsCStyleOrFunctionalCast = IgnoreBaseAccess;
|
||||
|
||||
Kind = CK_BitCast;
|
||||
|
||||
if (!IsCStyleOrFunctionalCast && !FromType->isAnyPointerType() &&
|
||||
if (Diagnose && !IsCStyleOrFunctionalCast && !FromType->isAnyPointerType() &&
|
||||
From->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNotNull) ==
|
||||
Expr::NPCK_ZeroExpression) {
|
||||
Expr::NPCK_ZeroExpression) {
|
||||
if (Context.hasSameUnqualifiedType(From->getType(), Context.BoolTy))
|
||||
DiagRuntimeBehavior(From->getExprLoc(), From,
|
||||
PDiag(diag::warn_impcast_bool_to_null_pointer)
|
||||
|
@ -2713,18 +2714,24 @@ bool Sema::CheckPointerConversion(Expr *From, QualType ToType,
|
|||
!Context.hasSameUnqualifiedType(FromPointeeType, ToPointeeType)) {
|
||||
// We must have a derived-to-base conversion. Check an
|
||||
// ambiguous or inaccessible conversion.
|
||||
if (CheckDerivedToBaseConversion(FromPointeeType, ToPointeeType,
|
||||
From->getExprLoc(),
|
||||
From->getSourceRange(), &BasePath,
|
||||
IgnoreBaseAccess))
|
||||
unsigned InaccessibleID = 0;
|
||||
unsigned AmbigiousID = 0;
|
||||
if (Diagnose) {
|
||||
InaccessibleID = diag::err_upcast_to_inaccessible_base;
|
||||
AmbigiousID = diag::err_ambiguous_derived_to_base_conv;
|
||||
}
|
||||
if (CheckDerivedToBaseConversion(
|
||||
FromPointeeType, ToPointeeType, InaccessibleID, AmbigiousID,
|
||||
From->getExprLoc(), From->getSourceRange(), DeclarationName(),
|
||||
&BasePath, IgnoreBaseAccess))
|
||||
return true;
|
||||
|
||||
// The conversion was successful.
|
||||
Kind = CK_DerivedToBase;
|
||||
}
|
||||
|
||||
if (!IsCStyleOrFunctionalCast && FromPointeeType->isFunctionType() &&
|
||||
ToPointeeType->isVoidType()) {
|
||||
if (Diagnose && !IsCStyleOrFunctionalCast &&
|
||||
FromPointeeType->isFunctionType() && ToPointeeType->isVoidType()) {
|
||||
assert(getLangOpts().MSVCCompat &&
|
||||
"this should only be possible with MSVCCompat!");
|
||||
Diag(From->getExprLoc(), diag::ext_ms_impcast_fn_obj)
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fsyntax-only -verify %s -fobjc-arc
|
||||
//
|
||||
// These tests exist as a means to help ensure that diagnostics aren't printed
|
||||
// in overload resolution in ObjC.
|
||||
|
||||
struct Type1 { int a; };
|
||||
@interface Iface1 @end
|
||||
|
||||
@interface NeverCalled
|
||||
- (void) test:(struct Type1 *)arg;
|
||||
@end
|
||||
|
||||
@interface TakesIface1
|
||||
- (void) test:(Iface1 *)arg;
|
||||
@end
|
||||
|
||||
// PR26085, rdar://problem/24111333
|
||||
void testTakesIface1(id x, Iface1 *arg) {
|
||||
// This should resolve silently to `TakesIface1`.
|
||||
[x test:arg];
|
||||
}
|
||||
|
||||
@class NSString;
|
||||
@interface NeverCalledv2
|
||||
- (void) testStr:(NSString *)arg;
|
||||
@end
|
||||
|
||||
@interface TakesVanillaConstChar
|
||||
- (void) testStr:(const void *)a;
|
||||
@end
|
||||
|
||||
// Not called out explicitly by PR26085, but related.
|
||||
void testTakesNSString(id x) {
|
||||
// Overload resolution should not emit a diagnostic about needing to add an
|
||||
// '@' before "someStringLiteral".
|
||||
[x testStr:"someStringLiteral"];
|
||||
}
|
||||
|
||||
typedef const void *CFTypeRef;
|
||||
id CreateSomething();
|
||||
|
||||
@interface NeverCalledv3
|
||||
- (void) testCFTypeRef:(struct Type1 *)arg;
|
||||
@end
|
||||
|
||||
@interface TakesCFTypeRef
|
||||
- (void) testCFTypeRef:(CFTypeRef)arg;
|
||||
@end
|
||||
|
||||
// Not called out explicitly by PR26085, but related.
|
||||
void testTakesCFTypeRef(id x) {
|
||||
// Overload resolution should occur silently, select the CFTypeRef overload,
|
||||
// and produce a single complaint. (with notes)
|
||||
[x testCFTypeRef:CreateSomething()]; // expected-error{{implicit conversion of Objective-C pointer type 'id' to C pointer type 'CFTypeRef'}} expected-note{{use __bridge}} expected-note{{use __bridge_retained}}
|
||||
}
|
Loading…
Reference in New Issue