summaryrefslogtreecommitdiffstats
path: root/lib/Sema/SemaStmt.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Sema/SemaStmt.cpp')
-rw-r--r--lib/Sema/SemaStmt.cpp57
1 files changed, 36 insertions, 21 deletions
diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp
index fd65c32..791de8c 100644
--- a/lib/Sema/SemaStmt.cpp
+++ b/lib/Sema/SemaStmt.cpp
@@ -119,7 +119,13 @@ void Sema::DiagnoseUnusedExprResult(const Stmt *S) {
}
}
}
-
+ else if (const ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(E)) {
+ const ObjCMethodDecl *MD = ME->getMethodDecl();
+ if (MD && MD->getAttr<WarnUnusedResultAttr>()) {
+ Diag(Loc, diag::warn_unused_call) << R1 << R2 << "warn_unused_result";
+ return;
+ }
+ }
Diag(Loc, DiagID) << R1 << R2;
}
@@ -427,48 +433,50 @@ static bool CheckCXXSwitchCondition(Sema &S, SourceLocation SwitchLoc,
// Make sure that the condition expression has a complete type,
// otherwise we'll never find any conversions.
if (S.RequireCompleteType(SwitchLoc, CondType,
- PDiag(diag::err_switch_incomplete_class_type)
+ S.PDiag(diag::err_switch_incomplete_class_type)
<< CondExpr->getSourceRange()))
return true;
- llvm::SmallVector<CXXConversionDecl *, 4> ViableConversions;
- llvm::SmallVector<CXXConversionDecl *, 4> ExplicitConversions;
+ UnresolvedSet<4> ViableConversions;
+ UnresolvedSet<4> ExplicitConversions;
if (const RecordType *RecordTy = CondType->getAs<RecordType>()) {
const UnresolvedSetImpl *Conversions
= cast<CXXRecordDecl>(RecordTy->getDecl())
->getVisibleConversionFunctions();
for (UnresolvedSetImpl::iterator I = Conversions->begin(),
E = Conversions->end(); I != E; ++I) {
- if (CXXConversionDecl *Conversion = dyn_cast<CXXConversionDecl>(*I))
+ if (CXXConversionDecl *Conversion
+ = dyn_cast<CXXConversionDecl>((*I)->getUnderlyingDecl()))
if (Conversion->getConversionType().getNonReferenceType()
->isIntegralType()) {
if (Conversion->isExplicit())
- ExplicitConversions.push_back(Conversion);
+ ExplicitConversions.addDecl(I.getDecl(), I.getAccess());
else
- ViableConversions.push_back(Conversion);
+ ViableConversions.addDecl(I.getDecl(), I.getAccess());
}
}
switch (ViableConversions.size()) {
case 0:
if (ExplicitConversions.size() == 1) {
+ DeclAccessPair Found = ExplicitConversions[0];
+ CXXConversionDecl *Conversion =
+ cast<CXXConversionDecl>(Found->getUnderlyingDecl());
// The user probably meant to invoke the given explicit
// conversion; use it.
QualType ConvTy
- = ExplicitConversions[0]->getConversionType()
- .getNonReferenceType();
+ = Conversion->getConversionType().getNonReferenceType();
std::string TypeStr;
ConvTy.getAsStringInternal(TypeStr, S.Context.PrintingPolicy);
S.Diag(SwitchLoc, diag::err_switch_explicit_conversion)
<< CondType << ConvTy << CondExpr->getSourceRange()
- << CodeModificationHint::CreateInsertion(CondExpr->getLocStart(),
- "static_cast<" + TypeStr + ">(")
- << CodeModificationHint::CreateInsertion(
+ << FixItHint::CreateInsertion(CondExpr->getLocStart(),
+ "static_cast<" + TypeStr + ">(")
+ << FixItHint::CreateInsertion(
S.PP.getLocForEndOfToken(CondExpr->getLocEnd()),
")");
- S.Diag(ExplicitConversions[0]->getLocation(),
- diag::note_switch_conversion)
+ S.Diag(Conversion->getLocation(), diag::note_switch_conversion)
<< ConvTy->isEnumeralType() << ConvTy;
// If we aren't in a SFINAE context, build a call to the
@@ -476,25 +484,32 @@ static bool CheckCXXSwitchCondition(Sema &S, SourceLocation SwitchLoc,
if (S.isSFINAEContext())
return true;
- CondExpr = S.BuildCXXMemberCallExpr(CondExpr, ExplicitConversions[0]);
+ S.CheckMemberOperatorAccess(CondExpr->getExprLoc(),
+ CondExpr, 0, Found);
+ CondExpr = S.BuildCXXMemberCallExpr(CondExpr, Found, Conversion);
}
// We'll complain below about a non-integral condition type.
break;
- case 1:
+ case 1: {
// Apply this conversion.
- CondExpr = S.BuildCXXMemberCallExpr(CondExpr, ViableConversions[0]);
+ DeclAccessPair Found = ViableConversions[0];
+ S.CheckMemberOperatorAccess(CondExpr->getExprLoc(),
+ CondExpr, 0, Found);
+ CondExpr = S.BuildCXXMemberCallExpr(CondExpr, Found,
+ cast<CXXConversionDecl>(Found->getUnderlyingDecl()));
break;
+ }
default:
S.Diag(SwitchLoc, diag::err_switch_multiple_conversions)
<< CondType << CondExpr->getSourceRange();
for (unsigned I = 0, N = ViableConversions.size(); I != N; ++I) {
- QualType ConvTy
- = ViableConversions[I]->getConversionType().getNonReferenceType();
- S.Diag(ViableConversions[I]->getLocation(),
- diag::note_switch_conversion)
+ CXXConversionDecl *Conv
+ = cast<CXXConversionDecl>(ViableConversions[I]->getUnderlyingDecl());
+ QualType ConvTy = Conv->getConversionType().getNonReferenceType();
+ S.Diag(Conv->getLocation(), diag::note_switch_conversion)
<< ConvTy->isEnumeralType() << ConvTy;
}
return true;
OpenPOWER on IntegriCloud