summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r--clang/lib/Sema/SemaDeclCXX.cpp19
-rw-r--r--clang/lib/Sema/SemaExpr.cpp39
-rw-r--r--clang/lib/Sema/SemaExprObjC.cpp134
-rw-r--r--clang/lib/Sema/SemaOverload.cpp25
4 files changed, 124 insertions, 93 deletions
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 11f232934e5..82d81a85fa9 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -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);
}
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 3e89af625d1..d7cd4d4e4fa 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -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;
}
diff --git a/clang/lib/Sema/SemaExprObjC.cpp b/clang/lib/Sema/SemaExprObjC.cpp
index 1d86ca35412..c1fb906a5b1 100644
--- a/clang/lib/Sema/SemaExprObjC.cpp
+++ b/clang/lib/Sema/SemaExprObjC.cpp
@@ -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;
}
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 663da0c0e80..d6a0ff7dc3d 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -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)
OpenPOWER on IntegriCloud