diff options
Diffstat (limited to 'lib/Sema/SemaStmt.cpp')
-rw-r--r-- | lib/Sema/SemaStmt.cpp | 429 |
1 files changed, 247 insertions, 182 deletions
diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp index 377e2c4dfa23f..9e30c9a396c0a 100644 --- a/lib/Sema/SemaStmt.cpp +++ b/lib/Sema/SemaStmt.cpp @@ -42,12 +42,11 @@ using namespace clang; using namespace sema; -StmtResult Sema::ActOnExprStmt(ExprResult FE) { +StmtResult Sema::ActOnExprStmt(ExprResult FE, bool DiscardedValue) { if (FE.isInvalid()) return StmtError(); - FE = ActOnFinishFullExpr(FE.get(), FE.get()->getExprLoc(), - /*DiscardedValue*/ true); + FE = ActOnFinishFullExpr(FE.get(), FE.get()->getExprLoc(), DiscardedValue); if (FE.isInvalid()) return StmtError(); @@ -246,7 +245,7 @@ void Sema::DiagnoseUnusedExprResult(const Stmt *S) { // we might want to make a more specific diagnostic. Check for one of these // cases now. unsigned DiagID = diag::warn_unused_expr; - if (const ExprWithCleanups *Temps = dyn_cast<ExprWithCleanups>(E)) + if (const FullExpr *Temps = dyn_cast<FullExpr>(E)) E = Temps->getSubExpr(); if (const CXXBindTemporaryExpr *TempExpr = dyn_cast<CXXBindTemporaryExpr>(E)) E = TempExpr->getSubExpr(); @@ -259,17 +258,16 @@ void Sema::DiagnoseUnusedExprResult(const Stmt *S) { if (E->getType()->isVoidType()) return; + if (const Attr *A = CE->getUnusedResultAttr(Context)) { + Diag(Loc, diag::warn_unused_result) << A << R1 << R2; + return; + } + // If the callee has attribute pure, const, or warn_unused_result, warn with // a more specific message to make it clear what is happening. If the call // is written in a macro body, only warn if it has the warn_unused_result // attribute. if (const Decl *FD = CE->getCalleeDecl()) { - if (const Attr *A = isa<FunctionDecl>(FD) - ? cast<FunctionDecl>(FD)->getUnusedResultAttr() - : FD->getAttr<WarnUnusedResultAttr>()) { - Diag(Loc, diag::warn_unused_result) << A << R1 << R2; - return; - } if (ShouldSuppress) return; if (FD->hasAttr<PureAttr>()) { @@ -349,6 +347,10 @@ sema::CompoundScopeInfo &Sema::getCurCompoundScope() const { return getCurFunction()->CompoundScopes.back(); } +bool Sema::isCurCompoundStmtAStmtExpr() const { + return getCurCompoundScope().IsStmtExpr; +} + StmtResult Sema::ActOnCompoundStmt(SourceLocation L, SourceLocation R, ArrayRef<Stmt *> Elts, bool isStmtExpr) { const unsigned NumElts = Elts.size(); @@ -371,14 +373,6 @@ StmtResult Sema::ActOnCompoundStmt(SourceLocation L, SourceLocation R, Diag(D->getLocation(), diag::ext_mixed_decls_code); } } - // Warn about unused expressions in statements. - for (unsigned i = 0; i != NumElts; ++i) { - // Ignore statements that are last in a statement expression. - if (isStmtExpr && i == NumElts - 1) - continue; - - DiagnoseUnusedExprResult(Elts[i]); - } // Check for suspicious empty body (null statement) in `for' and `while' // statements. Don't do anything for template instantiations, this just adds @@ -462,25 +456,20 @@ Sema::ActOnCaseStmt(SourceLocation CaseLoc, ExprResult LHSVal, return StmtError(); } - CaseStmt *CS = new (Context) - CaseStmt(LHSVal.get(), RHSVal.get(), CaseLoc, DotDotDotLoc, ColonLoc); + auto *CS = CaseStmt::Create(Context, LHSVal.get(), RHSVal.get(), + CaseLoc, DotDotDotLoc, ColonLoc); getCurFunction()->SwitchStack.back().getPointer()->addSwitchCase(CS); return CS; } /// ActOnCaseStmtBody - This installs a statement as the body of a case. -void Sema::ActOnCaseStmtBody(Stmt *caseStmt, Stmt *SubStmt) { - DiagnoseUnusedExprResult(SubStmt); - - CaseStmt *CS = static_cast<CaseStmt*>(caseStmt); - CS->setSubStmt(SubStmt); +void Sema::ActOnCaseStmtBody(Stmt *S, Stmt *SubStmt) { + cast<CaseStmt>(S)->setSubStmt(SubStmt); } StmtResult Sema::ActOnDefaultStmt(SourceLocation DefaultLoc, SourceLocation ColonLoc, Stmt *SubStmt, Scope *CurScope) { - DiagnoseUnusedExprResult(SubStmt); - if (getCurFunction()->SwitchStack.empty()) { Diag(DefaultLoc, diag::err_default_not_in_switch); return SubStmt; @@ -551,12 +540,13 @@ Sema::ActOnIfStmt(SourceLocation IfLoc, bool IsConstexpr, Stmt *InitStmt, false); Expr *CondExpr = Cond.get().second; - if (!Diags.isIgnored(diag::warn_comma_operator, - CondExpr->getExprLoc())) + // Only call the CommaVisitor when not C89 due to differences in scope flags. + if ((getLangOpts().C99 || getLangOpts().CPlusPlus) && + !Diags.isIgnored(diag::warn_comma_operator, CondExpr->getExprLoc())) CommaVisitor(*this).Visit(CondExpr); if (!elseStmt) - DiagnoseEmptyStmtBody(CondExpr->getLocEnd(), thenStmt, + DiagnoseEmptyStmtBody(CondExpr->getEndLoc(), thenStmt, diag::warn_empty_if_body); return BuildIfStmt(IfLoc, IsConstexpr, InitStmt, Cond, thenStmt, ElseLoc, @@ -573,12 +563,8 @@ StmtResult Sema::BuildIfStmt(SourceLocation IfLoc, bool IsConstexpr, if (IsConstexpr || isa<ObjCAvailabilityCheckExpr>(Cond.get().second)) setFunctionHasBranchProtectedScope(); - DiagnoseUnusedExprResult(thenStmt); - DiagnoseUnusedExprResult(elseStmt); - - return new (Context) - IfStmt(Context, IfLoc, IsConstexpr, InitStmt, Cond.get().first, - Cond.get().second, thenStmt, ElseLoc, elseStmt); + return IfStmt::Create(Context, IfLoc, IsConstexpr, InitStmt, Cond.get().first, + Cond.get().second, thenStmt, ElseLoc, elseStmt); } namespace { @@ -631,8 +617,8 @@ static bool EqEnumVals(const std::pair<llvm::APSInt, EnumConstantDecl*>& lhs, /// GetTypeBeforeIntegralPromotion - Returns the pre-promotion type of /// potentially integral-promoted expression @p expr. static QualType GetTypeBeforeIntegralPromotion(const Expr *&E) { - if (const auto *CleanUps = dyn_cast<ExprWithCleanups>(E)) - E = CleanUps->getSubExpr(); + if (const auto *FE = dyn_cast<FullExpr>(E)) + E = FE->getSubExpr(); while (const auto *ImpCast = dyn_cast<ImplicitCastExpr>(E)) { if (ImpCast->getCastKind() != CK_IntegralCast) break; E = ImpCast->getSubExpr(); @@ -727,8 +713,7 @@ StmtResult Sema::ActOnStartOfSwitchStmt(SourceLocation SwitchLoc, setFunctionHasBranchIntoScope(); - SwitchStmt *SS = new (Context) - SwitchStmt(Context, InitStmt, Cond.get().first, CondExpr); + auto *SS = SwitchStmt::Create(Context, InitStmt, Cond.get().first, CondExpr); getCurFunction()->SwitchStack.push_back( FunctionScopeInfo::SwitchInfo(SS, false)); return SS; @@ -918,8 +903,8 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch, // Check the unconverted value is within the range of possible values of // the switch expression. - checkCaseValue(*this, Lo->getLocStart(), LoVal, - CondWidthBeforePromotion, CondIsSignedBeforePromotion); + checkCaseValue(*this, Lo->getBeginLoc(), LoVal, CondWidthBeforePromotion, + CondIsSignedBeforePromotion); // FIXME: This duplicates the check performed for warn_not_in_enum below. checkEnumTypesInSwitchStmt(*this, CondExprBeforePromotion, @@ -946,8 +931,11 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch, llvm::APSInt ConstantCondValue; bool HasConstantCond = false; if (!HasDependentValue && !TheDefaultStmt) { - HasConstantCond = CondExpr->EvaluateAsInt(ConstantCondValue, Context, + Expr::EvalResult Result; + HasConstantCond = CondExpr->EvaluateAsInt(Result, Context, Expr::SE_AllowSideEffects); + if (Result.Val.isInt()) + ConstantCondValue = Result.Val.getInt(); assert(!HasConstantCond || (ConstantCondValue.getBitWidth() == CondWidth && ConstantCondValue.isSigned() == CondIsSigned)); @@ -979,17 +967,17 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch, CaseVals[i-1].first.toString(CaseValStr); if (PrevString == CurrString) - Diag(CaseVals[i].second->getLHS()->getLocStart(), - diag::err_duplicate_case) << - (PrevString.empty() ? StringRef(CaseValStr) : PrevString); + Diag(CaseVals[i].second->getLHS()->getBeginLoc(), + diag::err_duplicate_case) + << (PrevString.empty() ? StringRef(CaseValStr) : PrevString); else - Diag(CaseVals[i].second->getLHS()->getLocStart(), - diag::err_duplicate_case_differing_expr) << - (PrevString.empty() ? StringRef(CaseValStr) : PrevString) << - (CurrString.empty() ? StringRef(CaseValStr) : CurrString) << - CaseValStr; + Diag(CaseVals[i].second->getLHS()->getBeginLoc(), + diag::err_duplicate_case_differing_expr) + << (PrevString.empty() ? StringRef(CaseValStr) : PrevString) + << (CurrString.empty() ? StringRef(CaseValStr) : CurrString) + << CaseValStr; - Diag(CaseVals[i-1].second->getLHS()->getLocStart(), + Diag(CaseVals[i - 1].second->getLHS()->getBeginLoc(), diag::note_duplicate_case_prev); // FIXME: We really want to remove the bogus case stmt from the // substmt, but we have no way to do this right now. @@ -1018,7 +1006,7 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch, // Check the unconverted value is within the range of possible values of // the switch expression. - checkCaseValue(*this, Hi->getLocStart(), HiVal, + checkCaseValue(*this, Hi->getBeginLoc(), HiVal, CondWidthBeforePromotion, CondIsSignedBeforePromotion); // Convert the value to the same width/sign as the condition. @@ -1026,9 +1014,8 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch, // If the low value is bigger than the high value, the case is empty. if (LoVal > HiVal) { - Diag(CR->getLHS()->getLocStart(), diag::warn_case_empty_range) - << SourceRange(CR->getLHS()->getLocStart(), - Hi->getLocEnd()); + Diag(CR->getLHS()->getBeginLoc(), diag::warn_case_empty_range) + << SourceRange(CR->getLHS()->getBeginLoc(), Hi->getEndLoc()); CaseRanges.erase(CaseRanges.begin()+i); --i; --e; @@ -1082,9 +1069,9 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch, if (OverlapStmt) { // If we have a duplicate, report it. - Diag(CR->getLHS()->getLocStart(), diag::err_duplicate_case) - << OverlapVal.toString(10); - Diag(OverlapStmt->getLHS()->getLocStart(), + Diag(CR->getLHS()->getBeginLoc(), diag::err_duplicate_case) + << OverlapVal.toString(10); + Diag(OverlapStmt->getLHS()->getBeginLoc(), diag::note_duplicate_case_prev); // FIXME: We really want to remove the bogus case stmt from the // substmt, but we have no way to do this right now. @@ -1165,7 +1152,21 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch, SmallVector<DeclarationName,8> UnhandledNames; - for (EI = EnumVals.begin(); EI != EIEnd; EI++){ + for (EI = EnumVals.begin(); EI != EIEnd; EI++) { + // Don't warn about omitted unavailable EnumConstantDecls. + switch (EI->second->getAvailability()) { + case AR_Deprecated: + // Omitting a deprecated constant is ok; it should never materialize. + case AR_Unavailable: + continue; + + case AR_NotYetIntroduced: + // Partially available enum constants should be present. Note that we + // suppress -Wunguarded-availability diagnostics for such uses. + case AR_Available: + break; + } + // Drop unneeded case values while (CI != CaseVals.end() && CI->first < EI->first) CI++; @@ -1209,7 +1210,7 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch, } if (BodyStmt) - DiagnoseEmptyStmtBody(CondExpr->getLocEnd(), BodyStmt, + DiagnoseEmptyStmtBody(CondExpr->getEndLoc(), BodyStmt, diag::warn_empty_switch_body); // FIXME: If the case list was broken is some way, we don't have a good system @@ -1289,13 +1290,11 @@ StmtResult Sema::ActOnWhileStmt(SourceLocation WhileLoc, ConditionResult Cond, !Diags.isIgnored(diag::warn_comma_operator, CondVal.second->getExprLoc())) CommaVisitor(*this).Visit(CondVal.second); - DiagnoseUnusedExprResult(Body); - if (isa<NullStmt>(Body)) getCurCompoundScope().setHasEmptyLoopBodies(); - return new (Context) - WhileStmt(Context, CondVal.first, CondVal.second, Body, WhileLoc); + return WhileStmt::Create(Context, CondVal.first, CondVal.second, Body, + WhileLoc); } StmtResult @@ -1310,12 +1309,15 @@ Sema::ActOnDoStmt(SourceLocation DoLoc, Stmt *Body, return StmtError(); Cond = CondResult.get(); - CondResult = ActOnFinishFullExpr(Cond, DoLoc); + CondResult = ActOnFinishFullExpr(Cond, DoLoc, /*DiscardedValue*/ false); if (CondResult.isInvalid()) return StmtError(); Cond = CondResult.get(); - DiagnoseUnusedExprResult(Body); + // Only call the CommaVisitor for C89 due to differences in scope flags. + if (Cond && !getLangOpts().C99 && !getLangOpts().CPlusPlus && + !Diags.isIgnored(diag::warn_comma_operator, Cond->getExprLoc())) + CommaVisitor(*this).Visit(Cond); return new (Context) DoStmt(Body, Cond, DoLoc, WhileLoc, CondRParen); } @@ -1396,7 +1398,11 @@ namespace { void VisitDeclRefExpr(DeclRefExpr *E) { VarDecl *VD = dyn_cast<VarDecl>(E->getDecl()); - if (!VD) return; + if (!VD) { + // Don't allow unhandled Decl types. + Simple = false; + return; + } Ranges.push_back(E->getSourceRange()); @@ -1492,7 +1498,7 @@ namespace { if (!Second) return; if (S.Diags.isIgnored(diag::warn_variables_not_in_loop_body, - Second->getLocStart())) + Second->getBeginLoc())) return; PartialDiagnostic PDiag = S.PDiag(diag::warn_variables_not_in_loop_body); @@ -1634,6 +1640,8 @@ namespace { void VisitCXXForRangeStmt(const CXXForRangeStmt *S) { // Only visit the initialization of a for loop; the body // has a different break/continue scope. + if (const Stmt *Init = S->getInit()) + Visit(Init); if (const Stmt *Range = S->getRangeStmt()) Visit(Range); if (const Stmt *Begin = S->getBeginStmt()) @@ -1668,7 +1676,7 @@ namespace { if (!Body || !Third) return; if (S.Diags.isIgnored(diag::warn_redundant_loop_iteration, - Third->getLocStart())) + Third->getBeginLoc())) return; // Get the last statement from the loop body. @@ -1755,11 +1763,6 @@ StmtResult Sema::ActOnForStmt(SourceLocation ForLoc, SourceLocation LParenLoc, CommaVisitor(*this).Visit(Second.get().second); Expr *Third = third.release().getAs<Expr>(); - - DiagnoseUnusedExprResult(First); - DiagnoseUnusedExprResult(Third); - DiagnoseUnusedExprResult(Body); - if (isa<NullStmt>(Body)) getCurCompoundScope().setHasEmptyLoopBodies(); @@ -1779,7 +1782,7 @@ StmtResult Sema::ActOnForEachLValueExpr(Expr *E) { if (result.isInvalid()) return StmtError(); E = result.get(); - ExprResult FullExpr = ActOnFinishFullExpr(E); + ExprResult FullExpr = ActOnFinishFullExpr(E, /*DiscardedValue*/ false); if (FullExpr.isInvalid()) return StmtError(); return StmtResult(static_cast<Stmt*>(FullExpr.get())); @@ -1914,9 +1917,9 @@ Sema::ActOnObjCForCollectionStmt(SourceLocation ForLoc, } else { Expr *FirstE = cast<Expr>(First); if (!FirstE->isTypeDependent() && !FirstE->isLValue()) - return StmtError(Diag(First->getLocStart(), - diag::err_selector_element_not_lvalue) - << First->getSourceRange()); + return StmtError( + Diag(First->getBeginLoc(), diag::err_selector_element_not_lvalue) + << First->getSourceRange()); FirstType = static_cast<Expr*>(First)->getType(); if (FirstType.isConstQualified()) @@ -1933,7 +1936,8 @@ Sema::ActOnObjCForCollectionStmt(SourceLocation ForLoc, if (CollectionExprResult.isInvalid()) return StmtError(); - CollectionExprResult = ActOnFinishFullExpr(CollectionExprResult.get()); + CollectionExprResult = + ActOnFinishFullExpr(CollectionExprResult.get(), /*DiscardedValue*/ false); if (CollectionExprResult.isInvalid()) return StmtError(); @@ -2052,21 +2056,26 @@ static bool ObjCEnumerationCollection(Expr *Collection) { /// The body of the loop is not available yet, since it cannot be analysed until /// we have determined the type of the for-range-declaration. StmtResult Sema::ActOnCXXForRangeStmt(Scope *S, SourceLocation ForLoc, - SourceLocation CoawaitLoc, Stmt *First, - SourceLocation ColonLoc, Expr *Range, - SourceLocation RParenLoc, + SourceLocation CoawaitLoc, Stmt *InitStmt, + Stmt *First, SourceLocation ColonLoc, + Expr *Range, SourceLocation RParenLoc, BuildForRangeKind Kind) { if (!First) return StmtError(); - if (Range && ObjCEnumerationCollection(Range)) + if (Range && ObjCEnumerationCollection(Range)) { + // FIXME: Support init-statements in Objective-C++20 ranged for statement. + if (InitStmt) + return Diag(InitStmt->getBeginLoc(), diag::err_objc_for_range_init_stmt) + << InitStmt->getSourceRange(); return ActOnObjCForCollectionStmt(ForLoc, First, Range, RParenLoc); + } DeclStmt *DS = dyn_cast<DeclStmt>(First); assert(DS && "first part of for range not a decl stmt"); if (!DS->isSingleDecl()) { - Diag(DS->getStartLoc(), diag::err_type_defined_in_for_range); + Diag(DS->getBeginLoc(), diag::err_type_defined_in_for_range); return StmtError(); } @@ -2087,7 +2096,7 @@ StmtResult Sema::ActOnCXXForRangeStmt(Scope *S, SourceLocation ForLoc, // Build auto && __range = range-init // Divide by 2, since the variables are in the inner scope (loop body). const auto DepthStr = std::to_string(S->getDepth() / 2); - SourceLocation RangeLoc = Range->getLocStart(); + SourceLocation RangeLoc = Range->getBeginLoc(); VarDecl *RangeVar = BuildForRangeVarDecl(*this, RangeLoc, Context.getAutoRRefDeductType(), std::string("__range") + DepthStr); @@ -2106,10 +2115,10 @@ StmtResult Sema::ActOnCXXForRangeStmt(Scope *S, SourceLocation ForLoc, return StmtError(); } - return BuildCXXForRangeStmt(ForLoc, CoawaitLoc, ColonLoc, RangeDecl.get(), - /*BeginStmt=*/nullptr, /*EndStmt=*/nullptr, - /*Cond=*/nullptr, /*Inc=*/nullptr, - DS, RParenLoc, Kind); + return BuildCXXForRangeStmt( + ForLoc, CoawaitLoc, InitStmt, ColonLoc, RangeDecl.get(), + /*BeginStmt=*/nullptr, /*EndStmt=*/nullptr, + /*Cond=*/nullptr, /*Inc=*/nullptr, DS, RParenLoc, Kind); } /// Create the initialization, compare, and increment steps for @@ -2136,6 +2145,56 @@ BuildNonArrayForRange(Sema &SemaRef, Expr *BeginRange, Expr *EndRange, Sema::LookupMemberName); LookupResult EndMemberLookup(SemaRef, EndNameInfo, Sema::LookupMemberName); + auto BuildBegin = [&] { + *BEF = BEF_begin; + Sema::ForRangeStatus RangeStatus = + SemaRef.BuildForRangeBeginEndCall(ColonLoc, ColonLoc, BeginNameInfo, + BeginMemberLookup, CandidateSet, + BeginRange, BeginExpr); + + if (RangeStatus != Sema::FRS_Success) { + if (RangeStatus == Sema::FRS_DiagnosticIssued) + SemaRef.Diag(BeginRange->getBeginLoc(), diag::note_in_for_range) + << ColonLoc << BEF_begin << BeginRange->getType(); + return RangeStatus; + } + if (!CoawaitLoc.isInvalid()) { + // FIXME: getCurScope() should not be used during template instantiation. + // We should pick up the set of unqualified lookup results for operator + // co_await during the initial parse. + *BeginExpr = SemaRef.ActOnCoawaitExpr(SemaRef.getCurScope(), ColonLoc, + BeginExpr->get()); + if (BeginExpr->isInvalid()) + return Sema::FRS_DiagnosticIssued; + } + if (FinishForRangeVarDecl(SemaRef, BeginVar, BeginExpr->get(), ColonLoc, + diag::err_for_range_iter_deduction_failure)) { + NoteForRangeBeginEndFunction(SemaRef, BeginExpr->get(), *BEF); + return Sema::FRS_DiagnosticIssued; + } + return Sema::FRS_Success; + }; + + auto BuildEnd = [&] { + *BEF = BEF_end; + Sema::ForRangeStatus RangeStatus = + SemaRef.BuildForRangeBeginEndCall(ColonLoc, ColonLoc, EndNameInfo, + EndMemberLookup, CandidateSet, + EndRange, EndExpr); + if (RangeStatus != Sema::FRS_Success) { + if (RangeStatus == Sema::FRS_DiagnosticIssued) + SemaRef.Diag(EndRange->getBeginLoc(), diag::note_in_for_range) + << ColonLoc << BEF_end << EndRange->getType(); + return RangeStatus; + } + if (FinishForRangeVarDecl(SemaRef, EndVar, EndExpr->get(), ColonLoc, + diag::err_for_range_iter_deduction_failure)) { + NoteForRangeBeginEndFunction(SemaRef, EndExpr->get(), *BEF); + return Sema::FRS_DiagnosticIssued; + } + return Sema::FRS_Success; + }; + if (CXXRecordDecl *D = RangeType->getAsCXXRecordDecl()) { // - if _RangeT is a class type, the unqualified-ids begin and end are // looked up in the scope of class _RangeT as if by class member access @@ -2143,68 +2202,62 @@ BuildNonArrayForRange(Sema &SemaRef, Expr *BeginRange, Expr *EndRange, // declaration, begin-expr and end-expr are __range.begin() and // __range.end(), respectively; SemaRef.LookupQualifiedName(BeginMemberLookup, D); + if (BeginMemberLookup.isAmbiguous()) + return Sema::FRS_DiagnosticIssued; + SemaRef.LookupQualifiedName(EndMemberLookup, D); + if (EndMemberLookup.isAmbiguous()) + return Sema::FRS_DiagnosticIssued; if (BeginMemberLookup.empty() != EndMemberLookup.empty()) { - SourceLocation RangeLoc = BeginVar->getLocation(); - *BEF = BeginMemberLookup.empty() ? BEF_end : BEF_begin; - - SemaRef.Diag(RangeLoc, diag::err_for_range_member_begin_end_mismatch) - << RangeLoc << BeginRange->getType() << *BEF; - return Sema::FRS_DiagnosticIssued; + // Look up the non-member form of the member we didn't find, first. + // This way we prefer a "no viable 'end'" diagnostic over a "i found + // a 'begin' but ignored it because there was no member 'end'" + // diagnostic. + auto BuildNonmember = [&]( + BeginEndFunction BEFFound, LookupResult &Found, + llvm::function_ref<Sema::ForRangeStatus()> BuildFound, + llvm::function_ref<Sema::ForRangeStatus()> BuildNotFound) { + LookupResult OldFound = std::move(Found); + Found.clear(); + + if (Sema::ForRangeStatus Result = BuildNotFound()) + return Result; + + switch (BuildFound()) { + case Sema::FRS_Success: + return Sema::FRS_Success; + + case Sema::FRS_NoViableFunction: + SemaRef.Diag(BeginRange->getBeginLoc(), diag::err_for_range_invalid) + << BeginRange->getType() << BEFFound; + CandidateSet->NoteCandidates(SemaRef, OCD_AllCandidates, BeginRange); + LLVM_FALLTHROUGH; + + case Sema::FRS_DiagnosticIssued: + for (NamedDecl *D : OldFound) { + SemaRef.Diag(D->getLocation(), + diag::note_for_range_member_begin_end_ignored) + << BeginRange->getType() << BEFFound; + } + return Sema::FRS_DiagnosticIssued; + } + llvm_unreachable("unexpected ForRangeStatus"); + }; + if (BeginMemberLookup.empty()) + return BuildNonmember(BEF_end, EndMemberLookup, BuildEnd, BuildBegin); + return BuildNonmember(BEF_begin, BeginMemberLookup, BuildBegin, BuildEnd); } } else { // - otherwise, begin-expr and end-expr are begin(__range) and // end(__range), respectively, where begin and end are looked up with // argument-dependent lookup (3.4.2). For the purposes of this name // lookup, namespace std is an associated namespace. - - } - - *BEF = BEF_begin; - Sema::ForRangeStatus RangeStatus = - SemaRef.BuildForRangeBeginEndCall(ColonLoc, ColonLoc, BeginNameInfo, - BeginMemberLookup, CandidateSet, - BeginRange, BeginExpr); - - if (RangeStatus != Sema::FRS_Success) { - if (RangeStatus == Sema::FRS_DiagnosticIssued) - SemaRef.Diag(BeginRange->getLocStart(), diag::note_in_for_range) - << ColonLoc << BEF_begin << BeginRange->getType(); - return RangeStatus; - } - if (!CoawaitLoc.isInvalid()) { - // FIXME: getCurScope() should not be used during template instantiation. - // We should pick up the set of unqualified lookup results for operator - // co_await during the initial parse. - *BeginExpr = SemaRef.ActOnCoawaitExpr(SemaRef.getCurScope(), ColonLoc, - BeginExpr->get()); - if (BeginExpr->isInvalid()) - return Sema::FRS_DiagnosticIssued; - } - if (FinishForRangeVarDecl(SemaRef, BeginVar, BeginExpr->get(), ColonLoc, - diag::err_for_range_iter_deduction_failure)) { - NoteForRangeBeginEndFunction(SemaRef, BeginExpr->get(), *BEF); - return Sema::FRS_DiagnosticIssued; } - *BEF = BEF_end; - RangeStatus = - SemaRef.BuildForRangeBeginEndCall(ColonLoc, ColonLoc, EndNameInfo, - EndMemberLookup, CandidateSet, - EndRange, EndExpr); - if (RangeStatus != Sema::FRS_Success) { - if (RangeStatus == Sema::FRS_DiagnosticIssued) - SemaRef.Diag(EndRange->getLocStart(), diag::note_in_for_range) - << ColonLoc << BEF_end << EndRange->getType(); - return RangeStatus; - } - if (FinishForRangeVarDecl(SemaRef, EndVar, EndExpr->get(), ColonLoc, - diag::err_for_range_iter_deduction_failure)) { - NoteForRangeBeginEndFunction(SemaRef, EndExpr->get(), *BEF); - return Sema::FRS_DiagnosticIssued; - } - return Sema::FRS_Success; + if (Sema::ForRangeStatus Result = BuildBegin()) + return Result; + return BuildEnd(); } /// Speculatively attempt to dereference an invalid range expression. @@ -2213,6 +2266,7 @@ BuildNonArrayForRange(Sema &SemaRef, Expr *BeginRange, Expr *EndRange, static StmtResult RebuildForRangeWithDereference(Sema &SemaRef, Scope *S, SourceLocation ForLoc, SourceLocation CoawaitLoc, + Stmt *InitStmt, Stmt *LoopVarDecl, SourceLocation ColonLoc, Expr *Range, @@ -2229,8 +2283,8 @@ static StmtResult RebuildForRangeWithDereference(Sema &SemaRef, Scope *S, return StmtResult(); StmtResult SR = SemaRef.ActOnCXXForRangeStmt( - S, ForLoc, CoawaitLoc, LoopVarDecl, ColonLoc, AdjustedRange.get(), - RParenLoc, Sema::BFRK_Check); + S, ForLoc, CoawaitLoc, InitStmt, LoopVarDecl, ColonLoc, + AdjustedRange.get(), RParenLoc, Sema::BFRK_Check); if (SR.isInvalid()) return StmtResult(); } @@ -2240,9 +2294,9 @@ static StmtResult RebuildForRangeWithDereference(Sema &SemaRef, Scope *S, // case there are any other (non-fatal) problems with it. SemaRef.Diag(RangeLoc, diag::err_for_range_dereference) << Range->getType() << FixItHint::CreateInsertion(RangeLoc, "*"); - return SemaRef.ActOnCXXForRangeStmt(S, ForLoc, CoawaitLoc, LoopVarDecl, - ColonLoc, AdjustedRange.get(), RParenLoc, - Sema::BFRK_Rebuild); + return SemaRef.ActOnCXXForRangeStmt( + S, ForLoc, CoawaitLoc, InitStmt, LoopVarDecl, ColonLoc, + AdjustedRange.get(), RParenLoc, Sema::BFRK_Rebuild); } namespace { @@ -2262,12 +2316,13 @@ struct InvalidateOnErrorScope { } /// BuildCXXForRangeStmt - Build or instantiate a C++11 for-range statement. -StmtResult -Sema::BuildCXXForRangeStmt(SourceLocation ForLoc, SourceLocation CoawaitLoc, - SourceLocation ColonLoc, Stmt *RangeDecl, - Stmt *Begin, Stmt *End, Expr *Cond, - Expr *Inc, Stmt *LoopVarDecl, - SourceLocation RParenLoc, BuildForRangeKind Kind) { +StmtResult Sema::BuildCXXForRangeStmt(SourceLocation ForLoc, + SourceLocation CoawaitLoc, Stmt *InitStmt, + SourceLocation ColonLoc, Stmt *RangeDecl, + Stmt *Begin, Stmt *End, Expr *Cond, + Expr *Inc, Stmt *LoopVarDecl, + SourceLocation RParenLoc, + BuildForRangeKind Kind) { // FIXME: This should not be used during template instantiation. We should // pick up the set of unqualified lookup results for the != and + operators // in the initial parse. @@ -2451,8 +2506,8 @@ Sema::BuildCXXForRangeStmt(SourceLocation ForLoc, SourceLocation CoawaitLoc, QualType ArrayTy = PVD->getOriginalType(); QualType PointerTy = PVD->getType(); if (PointerTy->isPointerType() && ArrayTy->isArrayType()) { - Diag(Range->getLocStart(), diag::err_range_on_array_parameter) - << RangeLoc << PVD << ArrayTy << PointerTy; + Diag(Range->getBeginLoc(), diag::err_range_on_array_parameter) + << RangeLoc << PVD << ArrayTy << PointerTy; Diag(PVD->getLocation(), diag::note_declared_at); return StmtError(); } @@ -2462,7 +2517,7 @@ Sema::BuildCXXForRangeStmt(SourceLocation ForLoc, SourceLocation CoawaitLoc, // If building the range failed, try dereferencing the range expression // unless a diagnostic was issued or the end function is problematic. StmtResult SR = RebuildForRangeWithDereference(*this, S, ForLoc, - CoawaitLoc, + CoawaitLoc, InitStmt, LoopVarDecl, ColonLoc, Range, RangeLoc, RParenLoc); @@ -2473,7 +2528,7 @@ Sema::BuildCXXForRangeStmt(SourceLocation ForLoc, SourceLocation CoawaitLoc, // Otherwise, emit diagnostics if we haven't already. if (RangeStatus == FRS_NoViableFunction) { Expr *Range = BEFFailure ? EndRangeRef.get() : BeginRangeRef.get(); - Diag(Range->getLocStart(), diag::err_for_range_invalid) + Diag(Range->getBeginLoc(), diag::err_for_range_invalid) << RangeLoc << Range->getType() << BEFFailure; CandidateSet.NoteCandidates(*this, OCD_AllCandidates, Range); } @@ -2519,7 +2574,8 @@ Sema::BuildCXXForRangeStmt(SourceLocation ForLoc, SourceLocation CoawaitLoc, if (!NotEqExpr.isInvalid()) NotEqExpr = CheckBooleanCondition(ColonLoc, NotEqExpr.get()); if (!NotEqExpr.isInvalid()) - NotEqExpr = ActOnFinishFullExpr(NotEqExpr.get()); + NotEqExpr = + ActOnFinishFullExpr(NotEqExpr.get(), /*DiscardedValue*/ false); if (NotEqExpr.isInvalid()) { Diag(RangeLoc, diag::note_for_range_invalid_iterator) << RangeLoc << 0 << BeginRangeRef.get()->getType(); @@ -2542,7 +2598,7 @@ Sema::BuildCXXForRangeStmt(SourceLocation ForLoc, SourceLocation CoawaitLoc, // co_await during the initial parse. IncrExpr = ActOnCoawaitExpr(S, CoawaitLoc, IncrExpr.get()); if (!IncrExpr.isInvalid()) - IncrExpr = ActOnFinishFullExpr(IncrExpr.get()); + IncrExpr = ActOnFinishFullExpr(IncrExpr.get(), /*DiscardedValue*/ false); if (IncrExpr.isInvalid()) { Diag(RangeLoc, diag::note_for_range_invalid_iterator) << RangeLoc << 2 << BeginRangeRef.get()->getType() ; @@ -2579,7 +2635,7 @@ Sema::BuildCXXForRangeStmt(SourceLocation ForLoc, SourceLocation CoawaitLoc, return StmtResult(); return new (Context) CXXForRangeStmt( - RangeDS, cast_or_null<DeclStmt>(BeginDeclStmt.get()), + InitStmt, RangeDS, cast_or_null<DeclStmt>(BeginDeclStmt.get()), cast_or_null<DeclStmt>(EndDeclStmt.get()), NotEqExpr.get(), IncrExpr.get(), LoopVarDS, /*Body=*/nullptr, ForLoc, CoawaitLoc, ColonLoc, RParenLoc); @@ -2660,7 +2716,7 @@ static void DiagnoseForRangeReferenceVariableCopies(Sema &SemaRef, NonReferenceType.removeLocalConst(); QualType NewReferenceType = SemaRef.Context.getLValueReferenceType(E->getType().withConst()); - SemaRef.Diag(VD->getLocStart(), diag::note_use_type_or_non_reference) + SemaRef.Diag(VD->getBeginLoc(), diag::note_use_type_or_non_reference) << NonReferenceType << NewReferenceType << VD->getSourceRange(); } else { // The range always returns a copy, so a temporary is always created. @@ -2669,7 +2725,7 @@ static void DiagnoseForRangeReferenceVariableCopies(Sema &SemaRef, << VD << RangeInitType; QualType NonReferenceType = VariableType.getNonReferenceType(); NonReferenceType.removeLocalConst(); - SemaRef.Diag(VD->getLocStart(), diag::note_use_non_reference_type) + SemaRef.Diag(VD->getBeginLoc(), diag::note_use_non_reference_type) << NonReferenceType << VD->getSourceRange(); } } @@ -2705,7 +2761,7 @@ static void DiagnoseForRangeConstVariableCopies(Sema &SemaRef, // if doing so will prevent a copy. SemaRef.Diag(VD->getLocation(), diag::warn_for_range_copy) << VD << VariableType << InitExpr->getType(); - SemaRef.Diag(VD->getLocStart(), diag::note_use_reference_type) + SemaRef.Diag(VD->getBeginLoc(), diag::note_use_reference_type) << SemaRef.Context.getLValueReferenceType(VariableType) << VD->getSourceRange(); } @@ -2721,11 +2777,11 @@ static void DiagnoseForRangeConstVariableCopies(Sema &SemaRef, static void DiagnoseForRangeVariableCopies(Sema &SemaRef, const CXXForRangeStmt *ForStmt) { if (SemaRef.Diags.isIgnored(diag::warn_for_range_const_reference_copy, - ForStmt->getLocStart()) && + ForStmt->getBeginLoc()) && SemaRef.Diags.isIgnored(diag::warn_for_range_variable_always_copy, - ForStmt->getLocStart()) && + ForStmt->getBeginLoc()) && SemaRef.Diags.isIgnored(diag::warn_for_range_copy, - ForStmt->getLocStart())) { + ForStmt->getBeginLoc())) { return; } @@ -2797,7 +2853,7 @@ Sema::ActOnIndirectGotoStmt(SourceLocation GotoLoc, SourceLocation StarLoc, return StmtError(); } - ExprResult ExprRes = ActOnFinishFullExpr(E); + ExprResult ExprRes = ActOnFinishFullExpr(E, /*DiscardedValue*/ false); if (ExprRes.isInvalid()) return StmtError(); E = ExprRes.get(); @@ -2951,7 +3007,7 @@ static void TryMoveInitialization(Sema& S, Expr *InitExpr = &AsRvalue; InitializationKind Kind = InitializationKind::CreateCopy( - Value->getLocStart(), Value->getLocStart()); + Value->getBeginLoc(), Value->getBeginLoc()); InitializationSequence Seq(S, Entity, Kind, InitExpr); @@ -3147,12 +3203,14 @@ Sema::ActOnCapScopeReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) { ExpressionEvaluationContext::DiscardedStatement && (HasDeducedReturnType || CurCap->HasImplicitReturnType)) { if (RetValExp) { - ExprResult ER = ActOnFinishFullExpr(RetValExp, ReturnLoc); + ExprResult ER = + ActOnFinishFullExpr(RetValExp, ReturnLoc, /*DiscardedValue*/ false); if (ER.isInvalid()) return StmtError(); RetValExp = ER.get(); } - return new (Context) ReturnStmt(ReturnLoc, RetValExp, nullptr); + return ReturnStmt::Create(Context, ReturnLoc, RetValExp, + /* NRVOCandidate=*/nullptr); } if (HasDeducedReturnType) { @@ -3273,13 +3331,14 @@ Sema::ActOnCapScopeReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) { } if (RetValExp) { - ExprResult ER = ActOnFinishFullExpr(RetValExp, ReturnLoc); + ExprResult ER = + ActOnFinishFullExpr(RetValExp, ReturnLoc, /*DiscardedValue*/ false); if (ER.isInvalid()) return StmtError(); RetValExp = ER.get(); } - ReturnStmt *Result = new (Context) ReturnStmt(ReturnLoc, RetValExp, - NRVOCandidate); + auto *Result = + ReturnStmt::Create(Context, ReturnLoc, RetValExp, NRVOCandidate); // If we need to check for the named return value optimization, // or if we need to infer the return type, @@ -3503,12 +3562,14 @@ StmtResult Sema::BuildReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) { ExpressionEvaluationContext::DiscardedStatement && FnRetType->getContainedAutoType()) { if (RetValExp) { - ExprResult ER = ActOnFinishFullExpr(RetValExp, ReturnLoc); + ExprResult ER = + ActOnFinishFullExpr(RetValExp, ReturnLoc, /*DiscardedValue*/ false); if (ER.isInvalid()) return StmtError(); RetValExp = ER.get(); } - return new (Context) ReturnStmt(ReturnLoc, RetValExp, nullptr); + return ReturnStmt::Create(Context, ReturnLoc, RetValExp, + /* NRVOCandidate=*/nullptr); } // FIXME: Add a flag to the ScopeInfo to indicate whether we're performing @@ -3596,14 +3657,16 @@ StmtResult Sema::BuildReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) { } if (RetValExp) { - ExprResult ER = ActOnFinishFullExpr(RetValExp, ReturnLoc); + ExprResult ER = + ActOnFinishFullExpr(RetValExp, ReturnLoc, /*DiscardedValue*/ false); if (ER.isInvalid()) return StmtError(); RetValExp = ER.get(); } } - Result = new (Context) ReturnStmt(ReturnLoc, RetValExp, nullptr); + Result = ReturnStmt::Create(Context, ReturnLoc, RetValExp, + /* NRVOCandidate=*/nullptr); } else if (!RetValExp && !HasDependentReturnType) { FunctionDecl *FD = getCurFunctionDecl(); @@ -3625,7 +3688,8 @@ StmtResult Sema::BuildReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) { else Diag(ReturnLoc, DiagID) << getCurMethodDecl()->getDeclName() << 1/*meth*/; - Result = new (Context) ReturnStmt(ReturnLoc); + Result = ReturnStmt::Create(Context, ReturnLoc, /* RetExpr=*/nullptr, + /* NRVOCandidate=*/nullptr); } else { assert(RetValExp || HasDependentReturnType); const VarDecl *NRVOCandidate = nullptr; @@ -3673,12 +3737,13 @@ StmtResult Sema::BuildReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) { } if (RetValExp) { - ExprResult ER = ActOnFinishFullExpr(RetValExp, ReturnLoc); + ExprResult ER = + ActOnFinishFullExpr(RetValExp, ReturnLoc, /*DiscardedValue*/ false); if (ER.isInvalid()) return StmtError(); RetValExp = ER.get(); } - Result = new (Context) ReturnStmt(ReturnLoc, RetValExp, NRVOCandidate); + Result = ReturnStmt::Create(Context, ReturnLoc, RetValExp, NRVOCandidate); } // If we need to check for the named return value optimization, save the @@ -3726,7 +3791,7 @@ StmtResult Sema::BuildObjCAtThrowStmt(SourceLocation AtLoc, Expr *Throw) { if (Result.isInvalid()) return StmtError(); - Result = ActOnFinishFullExpr(Result.get()); + Result = ActOnFinishFullExpr(Result.get(), /*DiscardedValue*/ false); if (Result.isInvalid()) return StmtError(); Throw = Result.get(); @@ -3798,7 +3863,7 @@ Sema::ActOnObjCAtSynchronizedOperand(SourceLocation atLoc, Expr *operand) { } // The operand to @synchronized is a full-expression. - return ActOnFinishFullExpr(operand); + return ActOnFinishFullExpr(operand, /*DiscardedValue*/ false); } StmtResult @@ -3969,7 +4034,7 @@ StmtResult Sema::ActOnCXXTryBlock(SourceLocation TryLoc, Stmt *TryBlock, // declarations that are invalid, since we can't usefully report on them. if (!H->getExceptionDecl()) { if (i < NumHandlers - 1) - return StmtError(Diag(H->getLocStart(), diag::err_early_catch_all)); + return StmtError(Diag(H->getBeginLoc(), diag::err_early_catch_all)); continue; } else if (H->getExceptionDecl()->isInvalidDecl()) continue; |