4808 lines · cpp
1//===--- SemaStmt.cpp - Semantic Analysis for Statements ------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file implements semantic analysis for statements.10//11//===----------------------------------------------------------------------===//12 13#include "CheckExprLifetime.h"14#include "clang/AST/ASTContext.h"15#include "clang/AST/ASTLambda.h"16#include "clang/AST/CXXInheritance.h"17#include "clang/AST/CharUnits.h"18#include "clang/AST/DeclObjC.h"19#include "clang/AST/DynamicRecursiveASTVisitor.h"20#include "clang/AST/EvaluatedExprVisitor.h"21#include "clang/AST/ExprCXX.h"22#include "clang/AST/ExprObjC.h"23#include "clang/AST/IgnoreExpr.h"24#include "clang/AST/StmtCXX.h"25#include "clang/AST/StmtObjC.h"26#include "clang/AST/TypeLoc.h"27#include "clang/AST/TypeOrdering.h"28#include "clang/Basic/TargetInfo.h"29#include "clang/Lex/Preprocessor.h"30#include "clang/Sema/EnterExpressionEvaluationContext.h"31#include "clang/Sema/Initialization.h"32#include "clang/Sema/Lookup.h"33#include "clang/Sema/Ownership.h"34#include "clang/Sema/Scope.h"35#include "clang/Sema/ScopeInfo.h"36#include "clang/Sema/SemaCUDA.h"37#include "clang/Sema/SemaObjC.h"38#include "clang/Sema/SemaOpenMP.h"39#include "llvm/ADT/ArrayRef.h"40#include "llvm/ADT/DenseMap.h"41#include "llvm/ADT/STLExtras.h"42#include "llvm/ADT/SmallVector.h"43#include "llvm/ADT/StringExtras.h"44 45using namespace clang;46using namespace sema;47 48StmtResult Sema::ActOnExprStmt(ExprResult FE, bool DiscardedValue) {49 if (FE.isInvalid())50 return StmtError();51 52 FE = ActOnFinishFullExpr(FE.get(), FE.get()->getExprLoc(), DiscardedValue);53 if (FE.isInvalid())54 return StmtError();55 56 // C99 6.8.3p2: The expression in an expression statement is evaluated as a57 // void expression for its side effects. Conversion to void allows any58 // operand, even incomplete types.59 60 // Same thing in for stmt first clause (when expr) and third clause.61 return StmtResult(FE.getAs<Stmt>());62}63 64 65StmtResult Sema::ActOnExprStmtError() {66 DiscardCleanupsInEvaluationContext();67 return StmtError();68}69 70StmtResult Sema::ActOnNullStmt(SourceLocation SemiLoc,71 bool HasLeadingEmptyMacro) {72 return new (Context) NullStmt(SemiLoc, HasLeadingEmptyMacro);73}74 75StmtResult Sema::ActOnDeclStmt(DeclGroupPtrTy dg, SourceLocation StartLoc,76 SourceLocation EndLoc) {77 DeclGroupRef DG = dg.get();78 79 // If we have an invalid decl, just return an error.80 if (DG.isNull()) return StmtError();81 82 return new (Context) DeclStmt(DG, StartLoc, EndLoc);83}84 85void Sema::ActOnForEachDeclStmt(DeclGroupPtrTy dg) {86 DeclGroupRef DG = dg.get();87 88 // If we don't have a declaration, or we have an invalid declaration,89 // just return.90 if (DG.isNull() || !DG.isSingleDecl())91 return;92 93 Decl *decl = DG.getSingleDecl();94 if (!decl || decl->isInvalidDecl())95 return;96 97 // Only variable declarations are permitted.98 VarDecl *var = dyn_cast<VarDecl>(decl);99 if (!var) {100 Diag(decl->getLocation(), diag::err_non_variable_decl_in_for);101 decl->setInvalidDecl();102 return;103 }104 105 // foreach variables are never actually initialized in the way that106 // the parser came up with.107 var->setInit(nullptr);108 109 // In ARC, we don't need to retain the iteration variable of a fast110 // enumeration loop. Rather than actually trying to catch that111 // during declaration processing, we remove the consequences here.112 if (getLangOpts().ObjCAutoRefCount) {113 QualType type = var->getType();114 115 // Only do this if we inferred the lifetime. Inferred lifetime116 // will show up as a local qualifier because explicit lifetime117 // should have shown up as an AttributedType instead.118 if (type.getLocalQualifiers().getObjCLifetime() == Qualifiers::OCL_Strong) {119 // Add 'const' and mark the variable as pseudo-strong.120 var->setType(type.withConst());121 var->setARCPseudoStrong(true);122 }123 }124}125 126/// Diagnose unused comparisons, both builtin and overloaded operators.127/// For '==' and '!=', suggest fixits for '=' or '|='.128///129/// Adding a cast to void (or other expression wrappers) will prevent the130/// warning from firing.131static bool DiagnoseUnusedComparison(Sema &S, const Expr *E) {132 SourceLocation Loc;133 bool CanAssign;134 enum { Equality, Inequality, Relational, ThreeWay } Kind;135 136 if (const BinaryOperator *Op = dyn_cast<BinaryOperator>(E)) {137 if (!Op->isComparisonOp())138 return false;139 140 if (Op->getOpcode() == BO_EQ)141 Kind = Equality;142 else if (Op->getOpcode() == BO_NE)143 Kind = Inequality;144 else if (Op->getOpcode() == BO_Cmp)145 Kind = ThreeWay;146 else {147 assert(Op->isRelationalOp());148 Kind = Relational;149 }150 Loc = Op->getOperatorLoc();151 CanAssign = Op->getLHS()->IgnoreParenImpCasts()->isLValue();152 } else if (const CXXOperatorCallExpr *Op = dyn_cast<CXXOperatorCallExpr>(E)) {153 switch (Op->getOperator()) {154 case OO_EqualEqual:155 Kind = Equality;156 break;157 case OO_ExclaimEqual:158 Kind = Inequality;159 break;160 case OO_Less:161 case OO_Greater:162 case OO_GreaterEqual:163 case OO_LessEqual:164 Kind = Relational;165 break;166 case OO_Spaceship:167 Kind = ThreeWay;168 break;169 default:170 return false;171 }172 173 Loc = Op->getOperatorLoc();174 CanAssign = Op->getArg(0)->IgnoreParenImpCasts()->isLValue();175 } else {176 // Not a typo-prone comparison.177 return false;178 }179 180 // Suppress warnings when the operator, suspicious as it may be, comes from181 // a macro expansion.182 if (S.SourceMgr.isMacroBodyExpansion(Loc))183 return false;184 185 S.Diag(Loc, diag::warn_unused_comparison)186 << (unsigned)Kind << E->getSourceRange();187 188 // If the LHS is a plausible entity to assign to, provide a fixit hint to189 // correct common typos.190 if (CanAssign) {191 if (Kind == Inequality)192 S.Diag(Loc, diag::note_inequality_comparison_to_or_assign)193 << FixItHint::CreateReplacement(Loc, "|=");194 else if (Kind == Equality)195 S.Diag(Loc, diag::note_equality_comparison_to_assign)196 << FixItHint::CreateReplacement(Loc, "=");197 }198 199 return true;200}201 202static bool DiagnoseNoDiscard(Sema &S, const NamedDecl *OffendingDecl,203 const WarnUnusedResultAttr *A, SourceLocation Loc,204 SourceRange R1, SourceRange R2, bool IsCtor) {205 if (!A)206 return false;207 StringRef Msg = A->getMessage();208 209 if (Msg.empty()) {210 if (OffendingDecl)211 return S.Diag(Loc, diag::warn_unused_return_type)212 << IsCtor << A << OffendingDecl << false << R1 << R2;213 if (IsCtor)214 return S.Diag(Loc, diag::warn_unused_constructor)215 << A << false << R1 << R2;216 return S.Diag(Loc, diag::warn_unused_result) << A << false << R1 << R2;217 }218 219 if (OffendingDecl)220 return S.Diag(Loc, diag::warn_unused_return_type)221 << IsCtor << A << OffendingDecl << true << Msg << R1 << R2;222 if (IsCtor)223 return S.Diag(Loc, diag::warn_unused_constructor)224 << A << true << Msg << R1 << R2;225 return S.Diag(Loc, diag::warn_unused_result) << A << true << Msg << R1 << R2;226}227 228namespace {229 230// Diagnoses unused expressions that call functions marked [[nodiscard]],231// [[gnu::warn_unused_result]] and similar.232// Additionally, a DiagID can be provided to emit a warning in additional233// contexts (such as for an unused LHS of a comma expression)234void DiagnoseUnused(Sema &S, const Expr *E, std::optional<unsigned> DiagID) {235 bool NoDiscardOnly = !DiagID.has_value();236 237 // If we are in an unevaluated expression context, then there can be no unused238 // results because the results aren't expected to be used in the first place.239 if (S.isUnevaluatedContext())240 return;241 242 SourceLocation ExprLoc = E->IgnoreParenImpCasts()->getExprLoc();243 // In most cases, we don't want to warn if the expression is written in a244 // macro body, or if the macro comes from a system header. If the offending245 // expression is a call to a function with the warn_unused_result attribute,246 // we warn no matter the location. Because of the order in which the various247 // checks need to happen, we factor out the macro-related test here.248 bool ShouldSuppress = S.SourceMgr.isMacroBodyExpansion(ExprLoc) ||249 S.SourceMgr.isInSystemMacro(ExprLoc);250 251 const Expr *WarnExpr;252 SourceLocation Loc;253 SourceRange R1, R2;254 if (!E->isUnusedResultAWarning(WarnExpr, Loc, R1, R2, S.Context))255 return;256 257 if (!NoDiscardOnly) {258 // If this is a GNU statement expression expanded from a macro, it is259 // probably unused because it is a function-like macro that can be used as260 // either an expression or statement. Don't warn, because it is almost261 // certainly a false positive.262 if (isa<StmtExpr>(E) && Loc.isMacroID())263 return;264 265 // Check if this is the UNREFERENCED_PARAMETER from the Microsoft headers.266 // That macro is frequently used to suppress "unused parameter" warnings,267 // but its implementation makes clang's -Wunused-value fire. Prevent this.268 if (isa<ParenExpr>(E->IgnoreImpCasts()) && Loc.isMacroID()) {269 SourceLocation SpellLoc = Loc;270 if (S.findMacroSpelling(SpellLoc, "UNREFERENCED_PARAMETER"))271 return;272 }273 }274 275 // Okay, we have an unused result. Depending on what the base expression is,276 // we might want to make a more specific diagnostic. Check for one of these277 // cases now.278 if (const FullExpr *Temps = dyn_cast<FullExpr>(E))279 E = Temps->getSubExpr();280 if (const CXXBindTemporaryExpr *TempExpr = dyn_cast<CXXBindTemporaryExpr>(E))281 E = TempExpr->getSubExpr();282 283 if (DiagnoseUnusedComparison(S, E))284 return;285 286 E = WarnExpr;287 if (const auto *Cast = dyn_cast<CastExpr>(E))288 if (Cast->getCastKind() == CK_NoOp ||289 Cast->getCastKind() == CK_ConstructorConversion ||290 Cast->getCastKind() == CK_IntegralCast)291 E = Cast->getSubExpr()->IgnoreImpCasts();292 293 if (const CallExpr *CE = dyn_cast<CallExpr>(E)) {294 if (E->getType()->isVoidType())295 return;296 297 auto [OffendingDecl, A] = CE->getUnusedResultAttr(S.Context);298 if (DiagnoseNoDiscard(S, OffendingDecl, A, Loc, R1, R2,299 /*isCtor=*/false))300 return;301 302 // If the callee has attribute pure, const, or warn_unused_result, warn with303 // a more specific message to make it clear what is happening. If the call304 // is written in a macro body, only warn if it has the warn_unused_result305 // attribute.306 if (const Decl *FD = CE->getCalleeDecl()) {307 if (ShouldSuppress)308 return;309 if (FD->hasAttr<PureAttr>()) {310 S.Diag(Loc, diag::warn_unused_call) << R1 << R2 << "pure";311 return;312 }313 if (FD->hasAttr<ConstAttr>()) {314 S.Diag(Loc, diag::warn_unused_call) << R1 << R2 << "const";315 return;316 }317 }318 } else if (const auto *CE = dyn_cast<CXXConstructExpr>(E)) {319 auto [OffendingDecl, A] = CE->getUnusedResultAttr(S.Context);320 if (DiagnoseNoDiscard(S, OffendingDecl, A, Loc, R1, R2,321 /*isCtor=*/true))322 return;323 } else if (const auto *ILE = dyn_cast<InitListExpr>(E)) {324 if (const TagDecl *TD = ILE->getType()->getAsTagDecl()) {325 326 if (DiagnoseNoDiscard(S, TD, TD->getAttr<WarnUnusedResultAttr>(), Loc, R1,327 R2, /*isCtor=*/false))328 return;329 }330 } else if (ShouldSuppress)331 return;332 333 E = WarnExpr;334 if (const ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(E)) {335 if (S.getLangOpts().ObjCAutoRefCount && ME->isDelegateInitCall()) {336 S.Diag(Loc, diag::err_arc_unused_init_message) << R1;337 return;338 }339 340 auto [OffendingDecl, A] = ME->getUnusedResultAttr(S.Context);341 if (DiagnoseNoDiscard(S, OffendingDecl, A, Loc, R1, R2,342 /*isCtor=*/false))343 return;344 } else if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E)) {345 const Expr *Source = POE->getSyntacticForm();346 // Handle the actually selected call of an OpenMP specialized call.347 if (S.LangOpts.OpenMP && isa<CallExpr>(Source) &&348 POE->getNumSemanticExprs() == 1 &&349 isa<CallExpr>(POE->getSemanticExpr(0)))350 return DiagnoseUnused(S, POE->getSemanticExpr(0), DiagID);351 if (isa<ObjCSubscriptRefExpr>(Source))352 DiagID = diag::warn_unused_container_subscript_expr;353 else if (isa<ObjCPropertyRefExpr>(Source))354 DiagID = diag::warn_unused_property_expr;355 } else if (const CXXFunctionalCastExpr *FC356 = dyn_cast<CXXFunctionalCastExpr>(E)) {357 const Expr *E = FC->getSubExpr();358 if (const CXXBindTemporaryExpr *TE = dyn_cast<CXXBindTemporaryExpr>(E))359 E = TE->getSubExpr();360 if (isa<CXXTemporaryObjectExpr>(E))361 return;362 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))363 if (const CXXRecordDecl *RD = CE->getType()->getAsCXXRecordDecl())364 if (!RD->getAttr<WarnUnusedAttr>())365 return;366 }367 368 if (NoDiscardOnly)369 return;370 371 // Diagnose "(void*) blah" as a typo for "(void) blah".372 if (const CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(E)) {373 TypeSourceInfo *TI = CE->getTypeInfoAsWritten();374 QualType T = TI->getType();375 376 // We really do want to use the non-canonical type here.377 if (T == S.Context.VoidPtrTy) {378 PointerTypeLoc TL = TI->getTypeLoc().castAs<PointerTypeLoc>();379 380 S.Diag(Loc, diag::warn_unused_voidptr)381 << FixItHint::CreateRemoval(TL.getStarLoc());382 return;383 }384 }385 386 // Tell the user to assign it into a variable to force a volatile load if this387 // isn't an array.388 if (E->isGLValue() && E->getType().isVolatileQualified() &&389 !E->getType()->isArrayType()) {390 S.Diag(Loc, diag::warn_unused_volatile) << R1 << R2;391 return;392 }393 394 // Do not diagnose use of a comma operator in a SFINAE context because the395 // type of the left operand could be used for SFINAE, so technically it is396 // *used*.397 if (DiagID == diag::warn_unused_comma_left_operand && S.isSFINAEContext())398 return;399 400 S.DiagIfReachable(Loc, llvm::ArrayRef<const Stmt *>(E),401 S.PDiag(*DiagID) << R1 << R2);402}403} // namespace404 405void Sema::DiagnoseUnusedExprResult(const Stmt *S, unsigned DiagID) {406 if (const LabelStmt *Label = dyn_cast_if_present<LabelStmt>(S))407 S = Label->getSubStmt();408 409 const Expr *E = dyn_cast_if_present<Expr>(S);410 if (!E)411 return;412 413 DiagnoseUnused(*this, E, DiagID);414}415 416void Sema::ActOnStartOfCompoundStmt(bool IsStmtExpr) {417 PushCompoundScope(IsStmtExpr);418}419 420void Sema::ActOnAfterCompoundStatementLeadingPragmas() {421 if (getCurFPFeatures().isFPConstrained()) {422 FunctionScopeInfo *FSI = getCurFunction();423 assert(FSI);424 FSI->setUsesFPIntrin();425 }426}427 428void Sema::ActOnFinishOfCompoundStmt() {429 PopCompoundScope();430}431 432sema::CompoundScopeInfo &Sema::getCurCompoundScope() const {433 return getCurFunction()->CompoundScopes.back();434}435 436StmtResult Sema::ActOnCompoundStmt(SourceLocation L, SourceLocation R,437 ArrayRef<Stmt *> Elts, bool isStmtExpr) {438 const unsigned NumElts = Elts.size();439 440 // If we're in C mode, check that we don't have any decls after stmts. If441 // so, emit an extension diagnostic in C89 and potentially a warning in later442 // versions.443 const unsigned MixedDeclsCodeID = getLangOpts().C99444 ? diag::warn_mixed_decls_code445 : diag::ext_mixed_decls_code;446 if (!getLangOpts().CPlusPlus && !Diags.isIgnored(MixedDeclsCodeID, L)) {447 // Note that __extension__ can be around a decl.448 unsigned i = 0;449 // Skip over all declarations.450 for (; i != NumElts && isa<DeclStmt>(Elts[i]); ++i)451 /*empty*/;452 453 // We found the end of the list or a statement. Scan for another declstmt.454 for (; i != NumElts && !isa<DeclStmt>(Elts[i]); ++i)455 /*empty*/;456 457 if (i != NumElts) {458 Decl *D = *cast<DeclStmt>(Elts[i])->decl_begin();459 Diag(D->getLocation(), MixedDeclsCodeID);460 }461 }462 463 // Check for suspicious empty body (null statement) in `for' and `while'464 // statements. Don't do anything for template instantiations, this just adds465 // noise.466 if (NumElts != 0 && !CurrentInstantiationScope &&467 getCurCompoundScope().HasEmptyLoopBodies) {468 for (unsigned i = 0; i != NumElts - 1; ++i)469 DiagnoseEmptyLoopBody(Elts[i], Elts[i + 1]);470 }471 472 // Calculate difference between FP options in this compound statement and in473 // the enclosing one. If this is a function body, take the difference against474 // default options. In this case the difference will indicate options that are475 // changed upon entry to the statement.476 FPOptions FPO = (getCurFunction()->CompoundScopes.size() == 1)477 ? FPOptions(getLangOpts())478 : getCurCompoundScope().InitialFPFeatures;479 FPOptionsOverride FPDiff = getCurFPFeatures().getChangesFrom(FPO);480 481 return CompoundStmt::Create(Context, Elts, FPDiff, L, R);482}483 484ExprResult485Sema::ActOnCaseExpr(SourceLocation CaseLoc, ExprResult Val) {486 if (!Val.get())487 return Val;488 489 if (DiagnoseUnexpandedParameterPack(Val.get()))490 return ExprError();491 492 // If we're not inside a switch, let the 'case' statement handling diagnose493 // this. Just clean up after the expression as best we can.494 if (getCurFunction()->SwitchStack.empty())495 return ActOnFinishFullExpr(Val.get(), Val.get()->getExprLoc(), false,496 getLangOpts().CPlusPlus11);497 498 Expr *CondExpr =499 getCurFunction()->SwitchStack.back().getPointer()->getCond();500 if (!CondExpr)501 return ExprError();502 QualType CondType = CondExpr->getType();503 504 auto CheckAndFinish = [&](Expr *E) {505 if (CondType->isDependentType() || E->isTypeDependent())506 return ExprResult(E);507 508 if (getLangOpts().CPlusPlus11) {509 // C++11 [stmt.switch]p2: the constant-expression shall be a converted510 // constant expression of the promoted type of the switch condition.511 llvm::APSInt TempVal;512 return CheckConvertedConstantExpression(E, CondType, TempVal,513 CCEKind::CaseValue);514 }515 516 ExprResult ER = E;517 if (!E->isValueDependent())518 ER = VerifyIntegerConstantExpression(E, AllowFoldKind::Allow);519 if (!ER.isInvalid())520 ER = DefaultLvalueConversion(ER.get());521 if (!ER.isInvalid())522 ER = ImpCastExprToType(ER.get(), CondType, CK_IntegralCast);523 if (!ER.isInvalid())524 ER = ActOnFinishFullExpr(ER.get(), ER.get()->getExprLoc(), false);525 return ER;526 };527 528 return CheckAndFinish(Val.get());529}530 531StmtResult532Sema::ActOnCaseStmt(SourceLocation CaseLoc, ExprResult LHSVal,533 SourceLocation DotDotDotLoc, ExprResult RHSVal,534 SourceLocation ColonLoc) {535 assert((LHSVal.isInvalid() || LHSVal.get()) && "missing LHS value");536 assert((DotDotDotLoc.isInvalid() ? RHSVal.isUnset()537 : RHSVal.isInvalid() || RHSVal.get()) &&538 "missing RHS value");539 540 if (getCurFunction()->SwitchStack.empty()) {541 Diag(CaseLoc, diag::err_case_not_in_switch);542 return StmtError();543 }544 545 if (LHSVal.isInvalid() || RHSVal.isInvalid()) {546 getCurFunction()->SwitchStack.back().setInt(true);547 return StmtError();548 }549 550 if (LangOpts.OpenACC &&551 getCurScope()->isInOpenACCComputeConstructScope(Scope::SwitchScope)) {552 Diag(CaseLoc, diag::err_acc_branch_in_out_compute_construct)553 << /*branch*/ 0 << /*into*/ 1;554 return StmtError();555 }556 557 auto *CS = CaseStmt::Create(Context, LHSVal.get(), RHSVal.get(),558 CaseLoc, DotDotDotLoc, ColonLoc);559 getCurFunction()->SwitchStack.back().getPointer()->addSwitchCase(CS);560 return CS;561}562 563void Sema::ActOnCaseStmtBody(Stmt *S, Stmt *SubStmt) {564 cast<CaseStmt>(S)->setSubStmt(SubStmt);565}566 567StmtResult568Sema::ActOnDefaultStmt(SourceLocation DefaultLoc, SourceLocation ColonLoc,569 Stmt *SubStmt, Scope *CurScope) {570 if (getCurFunction()->SwitchStack.empty()) {571 Diag(DefaultLoc, diag::err_default_not_in_switch);572 return SubStmt;573 }574 575 if (LangOpts.OpenACC &&576 getCurScope()->isInOpenACCComputeConstructScope(Scope::SwitchScope)) {577 Diag(DefaultLoc, diag::err_acc_branch_in_out_compute_construct)578 << /*branch*/ 0 << /*into*/ 1;579 return StmtError();580 }581 582 DefaultStmt *DS = new (Context) DefaultStmt(DefaultLoc, ColonLoc, SubStmt);583 getCurFunction()->SwitchStack.back().getPointer()->addSwitchCase(DS);584 return DS;585}586 587StmtResult588Sema::ActOnLabelStmt(SourceLocation IdentLoc, LabelDecl *TheDecl,589 SourceLocation ColonLoc, Stmt *SubStmt) {590 // If the label was multiply defined, reject it now.591 if (TheDecl->getStmt()) {592 Diag(IdentLoc, diag::err_redefinition_of_label) << TheDecl->getDeclName();593 Diag(TheDecl->getLocation(), diag::note_previous_definition);594 return SubStmt;595 }596 597 ReservedIdentifierStatus Status = TheDecl->isReserved(getLangOpts());598 if (isReservedInAllContexts(Status) &&599 !Context.getSourceManager().isInSystemHeader(IdentLoc))600 Diag(IdentLoc, diag::warn_reserved_extern_symbol)601 << TheDecl << static_cast<int>(Status);602 603 // If this label is in a compute construct scope, we need to make sure we604 // check gotos in/out.605 if (getCurScope()->isInOpenACCComputeConstructScope())606 setFunctionHasBranchProtectedScope();607 608 // OpenACC3.3 2.14.4:609 // The update directive is executable. It must not appear in place of the610 // statement following an 'if', 'while', 'do', 'switch', or 'label' in C or611 // C++.612 if (isa<OpenACCUpdateConstruct>(SubStmt)) {613 Diag(SubStmt->getBeginLoc(), diag::err_acc_update_as_body) << /*Label*/ 4;614 SubStmt = new (Context) NullStmt(SubStmt->getBeginLoc());615 }616 617 // Otherwise, things are good. Fill in the declaration and return it.618 LabelStmt *LS = new (Context) LabelStmt(IdentLoc, TheDecl, SubStmt);619 TheDecl->setStmt(LS);620 if (!TheDecl->isGnuLocal()) {621 TheDecl->setLocStart(IdentLoc);622 if (!TheDecl->isMSAsmLabel()) {623 // Don't update the location of MS ASM labels. These will result in624 // a diagnostic, and changing the location here will mess that up.625 TheDecl->setLocation(IdentLoc);626 }627 }628 return LS;629}630 631StmtResult Sema::BuildAttributedStmt(SourceLocation AttrsLoc,632 ArrayRef<const Attr *> Attrs,633 Stmt *SubStmt) {634 // FIXME: this code should move when a planned refactoring around statement635 // attributes lands.636 for (const auto *A : Attrs) {637 if (A->getKind() == attr::MustTail) {638 if (!checkAndRewriteMustTailAttr(SubStmt, *A)) {639 return SubStmt;640 }641 setFunctionHasMustTail();642 }643 }644 645 return AttributedStmt::Create(Context, AttrsLoc, Attrs, SubStmt);646}647 648StmtResult Sema::ActOnAttributedStmt(const ParsedAttributes &Attrs,649 Stmt *SubStmt) {650 SmallVector<const Attr *, 1> SemanticAttrs;651 ProcessStmtAttributes(SubStmt, Attrs, SemanticAttrs);652 if (!SemanticAttrs.empty())653 return BuildAttributedStmt(Attrs.Range.getBegin(), SemanticAttrs, SubStmt);654 // If none of the attributes applied, that's fine, we can recover by655 // returning the substatement directly instead of making an AttributedStmt656 // with no attributes on it.657 return SubStmt;658}659 660bool Sema::checkAndRewriteMustTailAttr(Stmt *St, const Attr &MTA) {661 ReturnStmt *R = cast<ReturnStmt>(St);662 Expr *E = R->getRetValue();663 664 if (CurContext->isDependentContext() || (E && E->isInstantiationDependent()))665 // We have to suspend our check until template instantiation time.666 return true;667 668 if (!checkMustTailAttr(St, MTA))669 return false;670 671 // FIXME: Replace Expr::IgnoreImplicitAsWritten() with this function.672 // Currently it does not skip implicit constructors in an initialization673 // context.674 auto IgnoreImplicitAsWritten = [](Expr *E) -> Expr * {675 return IgnoreExprNodes(E, IgnoreImplicitAsWrittenSingleStep,676 IgnoreElidableImplicitConstructorSingleStep);677 };678 679 // Now that we have verified that 'musttail' is valid here, rewrite the680 // return value to remove all implicit nodes, but retain parentheses.681 R->setRetValue(IgnoreImplicitAsWritten(E));682 return true;683}684 685bool Sema::checkMustTailAttr(const Stmt *St, const Attr &MTA) {686 assert(!CurContext->isDependentContext() &&687 "musttail cannot be checked from a dependent context");688 689 // FIXME: Add Expr::IgnoreParenImplicitAsWritten() with this definition.690 auto IgnoreParenImplicitAsWritten = [](const Expr *E) -> const Expr * {691 return IgnoreExprNodes(const_cast<Expr *>(E), IgnoreParensSingleStep,692 IgnoreImplicitAsWrittenSingleStep,693 IgnoreElidableImplicitConstructorSingleStep);694 };695 696 const Expr *E = cast<ReturnStmt>(St)->getRetValue();697 const auto *CE = dyn_cast_or_null<CallExpr>(IgnoreParenImplicitAsWritten(E));698 699 if (!CE) {700 Diag(St->getBeginLoc(), diag::err_musttail_needs_call) << &MTA;701 return false;702 }703 704 if (const FunctionDecl *CalleeDecl = CE->getDirectCallee();705 CalleeDecl && CalleeDecl->hasAttr<NotTailCalledAttr>()) {706 Diag(St->getBeginLoc(), diag::err_musttail_mismatch) << /*show-function-callee=*/true << CalleeDecl;707 Diag(CalleeDecl->getLocation(), diag::note_musttail_disabled_by_not_tail_called);708 return false;709 }710 711 if (const auto *EWC = dyn_cast<ExprWithCleanups>(E)) {712 if (EWC->cleanupsHaveSideEffects()) {713 Diag(St->getBeginLoc(), diag::err_musttail_needs_trivial_args) << &MTA;714 return false;715 }716 }717 718 // We need to determine the full function type (including "this" type, if any)719 // for both caller and callee.720 struct FuncType {721 enum {722 ft_non_member,723 ft_static_member,724 ft_non_static_member,725 ft_pointer_to_member,726 } MemberType = ft_non_member;727 728 QualType This;729 const FunctionProtoType *Func;730 const CXXMethodDecl *Method = nullptr;731 } CallerType, CalleeType;732 733 auto GetMethodType = [this, St, MTA](const CXXMethodDecl *CMD, FuncType &Type,734 bool IsCallee) -> bool {735 if (isa<CXXConstructorDecl, CXXDestructorDecl>(CMD)) {736 Diag(St->getBeginLoc(), diag::err_musttail_structors_forbidden)737 << IsCallee << isa<CXXDestructorDecl>(CMD);738 if (IsCallee)739 Diag(CMD->getBeginLoc(), diag::note_musttail_structors_forbidden)740 << isa<CXXDestructorDecl>(CMD);741 Diag(MTA.getLocation(), diag::note_tail_call_required) << &MTA;742 return false;743 }744 if (CMD->isStatic())745 Type.MemberType = FuncType::ft_static_member;746 else {747 Type.This = CMD->getFunctionObjectParameterType();748 Type.MemberType = FuncType::ft_non_static_member;749 }750 Type.Func = CMD->getType()->castAs<FunctionProtoType>();751 return true;752 };753 754 const auto *CallerDecl = dyn_cast<FunctionDecl>(CurContext);755 756 // Find caller function signature.757 if (!CallerDecl) {758 int ContextType;759 if (isa<BlockDecl>(CurContext))760 ContextType = 0;761 else if (isa<ObjCMethodDecl>(CurContext))762 ContextType = 1;763 else764 ContextType = 2;765 Diag(St->getBeginLoc(), diag::err_musttail_forbidden_from_this_context)766 << &MTA << ContextType;767 return false;768 } else if (const auto *CMD = dyn_cast<CXXMethodDecl>(CurContext)) {769 // Caller is a class/struct method.770 if (!GetMethodType(CMD, CallerType, false))771 return false;772 } else {773 // Caller is a non-method function.774 CallerType.Func = CallerDecl->getType()->getAs<FunctionProtoType>();775 }776 777 const Expr *CalleeExpr = CE->getCallee()->IgnoreParens();778 const auto *CalleeBinOp = dyn_cast<BinaryOperator>(CalleeExpr);779 SourceLocation CalleeLoc = CE->getCalleeDecl()780 ? CE->getCalleeDecl()->getBeginLoc()781 : St->getBeginLoc();782 783 // Find callee function signature.784 if (const CXXMethodDecl *CMD =785 dyn_cast_or_null<CXXMethodDecl>(CE->getCalleeDecl())) {786 // Call is: obj.method(), obj->method(), functor(), etc.787 if (!GetMethodType(CMD, CalleeType, true))788 return false;789 } else if (CalleeBinOp && CalleeBinOp->isPtrMemOp()) {790 // Call is: obj->*method_ptr or obj.*method_ptr791 const auto *MPT =792 CalleeBinOp->getRHS()->getType()->castAs<MemberPointerType>();793 CalleeType.This =794 Context.getCanonicalTagType(MPT->getMostRecentCXXRecordDecl());795 CalleeType.Func = MPT->getPointeeType()->castAs<FunctionProtoType>();796 CalleeType.MemberType = FuncType::ft_pointer_to_member;797 } else if (isa<CXXPseudoDestructorExpr>(CalleeExpr)) {798 Diag(St->getBeginLoc(), diag::err_musttail_structors_forbidden)799 << /* IsCallee = */ 1 << /* IsDestructor = */ 1;800 Diag(MTA.getLocation(), diag::note_tail_call_required) << &MTA;801 return false;802 } else {803 // Non-method function.804 CalleeType.Func =805 CalleeExpr->getType()->getPointeeType()->getAs<FunctionProtoType>();806 }807 808 // Both caller and callee must have a prototype (no K&R declarations).809 if (!CalleeType.Func || !CallerType.Func) {810 Diag(St->getBeginLoc(), diag::err_musttail_needs_prototype) << &MTA;811 if (!CalleeType.Func && CE->getDirectCallee()) {812 Diag(CE->getDirectCallee()->getBeginLoc(),813 diag::note_musttail_fix_non_prototype);814 }815 if (!CallerType.Func)816 Diag(CallerDecl->getBeginLoc(), diag::note_musttail_fix_non_prototype);817 return false;818 }819 820 // Caller and callee must have matching calling conventions.821 //822 // Some calling conventions are physically capable of supporting tail calls823 // even if the function types don't perfectly match. LLVM is currently too824 // strict to allow this, but if LLVM added support for this in the future, we825 // could exit early here and skip the remaining checks if the functions are826 // using such a calling convention.827 if (CallerType.Func->getCallConv() != CalleeType.Func->getCallConv()) {828 if (const auto *ND = dyn_cast_or_null<NamedDecl>(CE->getCalleeDecl()))829 Diag(St->getBeginLoc(), diag::err_musttail_callconv_mismatch)830 << true << ND->getDeclName();831 else832 Diag(St->getBeginLoc(), diag::err_musttail_callconv_mismatch) << false;833 Diag(CalleeLoc, diag::note_musttail_callconv_mismatch)834 << FunctionType::getNameForCallConv(CallerType.Func->getCallConv())835 << FunctionType::getNameForCallConv(CalleeType.Func->getCallConv());836 Diag(MTA.getLocation(), diag::note_tail_call_required) << &MTA;837 return false;838 }839 840 if (CalleeType.Func->isVariadic() || CallerType.Func->isVariadic()) {841 Diag(St->getBeginLoc(), diag::err_musttail_no_variadic) << &MTA;842 return false;843 }844 845 const auto *CalleeDecl = CE->getCalleeDecl();846 if (CalleeDecl && CalleeDecl->hasAttr<CXX11NoReturnAttr>()) {847 Diag(St->getBeginLoc(), diag::err_musttail_no_return) << &MTA;848 return false;849 }850 851 // Caller and callee must match in whether they have a "this" parameter.852 if (CallerType.This.isNull() != CalleeType.This.isNull()) {853 if (const auto *ND = dyn_cast_or_null<NamedDecl>(CE->getCalleeDecl())) {854 Diag(St->getBeginLoc(), diag::err_musttail_member_mismatch)855 << CallerType.MemberType << CalleeType.MemberType << true856 << ND->getDeclName();857 Diag(CalleeLoc, diag::note_musttail_callee_defined_here)858 << ND->getDeclName();859 } else860 Diag(St->getBeginLoc(), diag::err_musttail_member_mismatch)861 << CallerType.MemberType << CalleeType.MemberType << false;862 Diag(MTA.getLocation(), diag::note_tail_call_required) << &MTA;863 return false;864 }865 866 auto CheckTypesMatch = [this](FuncType CallerType, FuncType CalleeType,867 PartialDiagnostic &PD) -> bool {868 enum {869 ft_different_class,870 ft_parameter_arity,871 ft_parameter_mismatch,872 ft_return_type,873 };874 875 auto DoTypesMatch = [this, &PD](QualType A, QualType B,876 unsigned Select) -> bool {877 if (!Context.hasSimilarType(A, B)) {878 PD << Select << A.getUnqualifiedType() << B.getUnqualifiedType();879 return false;880 }881 return true;882 };883 884 if (!CallerType.This.isNull() &&885 !DoTypesMatch(CallerType.This, CalleeType.This, ft_different_class))886 return false;887 888 if (!DoTypesMatch(CallerType.Func->getReturnType(),889 CalleeType.Func->getReturnType(), ft_return_type))890 return false;891 892 if (CallerType.Func->getNumParams() != CalleeType.Func->getNumParams()) {893 PD << ft_parameter_arity << CallerType.Func->getNumParams()894 << CalleeType.Func->getNumParams();895 return false;896 }897 898 ArrayRef<QualType> CalleeParams = CalleeType.Func->getParamTypes();899 ArrayRef<QualType> CallerParams = CallerType.Func->getParamTypes();900 size_t N = CallerType.Func->getNumParams();901 for (size_t I = 0; I < N; I++) {902 if (!DoTypesMatch(CalleeParams[I], CallerParams[I],903 ft_parameter_mismatch)) {904 PD << static_cast<int>(I) + 1;905 return false;906 }907 }908 909 return true;910 };911 912 PartialDiagnostic PD = PDiag(diag::note_musttail_mismatch);913 if (!CheckTypesMatch(CallerType, CalleeType, PD)) {914 if (const auto *ND = dyn_cast_or_null<NamedDecl>(CE->getCalleeDecl()))915 Diag(St->getBeginLoc(), diag::err_musttail_mismatch)916 << true << ND->getDeclName();917 else918 Diag(St->getBeginLoc(), diag::err_musttail_mismatch) << false;919 Diag(CalleeLoc, PD);920 Diag(MTA.getLocation(), diag::note_tail_call_required) << &MTA;921 return false;922 }923 924 // The lifetimes of locals and incoming function parameters must end before925 // the call, because we can't have a stack frame to store them, so diagnose926 // any pointers or references to them passed into the musttail call.927 for (auto ArgExpr : CE->arguments()) {928 InitializedEntity Entity = InitializedEntity::InitializeParameter(929 Context, ArgExpr->getType(), false);930 checkExprLifetimeMustTailArg(*this, Entity, const_cast<Expr *>(ArgExpr));931 }932 933 return true;934}935 936namespace {937class CommaVisitor : public EvaluatedExprVisitor<CommaVisitor> {938 typedef EvaluatedExprVisitor<CommaVisitor> Inherited;939 Sema &SemaRef;940public:941 CommaVisitor(Sema &SemaRef) : Inherited(SemaRef.Context), SemaRef(SemaRef) {}942 void VisitBinaryOperator(BinaryOperator *E) {943 if (E->getOpcode() == BO_Comma)944 SemaRef.DiagnoseCommaOperator(E->getLHS(), E->getExprLoc());945 EvaluatedExprVisitor<CommaVisitor>::VisitBinaryOperator(E);946 }947};948}949 950StmtResult Sema::ActOnIfStmt(SourceLocation IfLoc,951 IfStatementKind StatementKind,952 SourceLocation LParenLoc, Stmt *InitStmt,953 ConditionResult Cond, SourceLocation RParenLoc,954 Stmt *thenStmt, SourceLocation ElseLoc,955 Stmt *elseStmt) {956 if (Cond.isInvalid())957 return StmtError();958 959 bool ConstevalOrNegatedConsteval =960 StatementKind == IfStatementKind::ConstevalNonNegated ||961 StatementKind == IfStatementKind::ConstevalNegated;962 963 Expr *CondExpr = Cond.get().second;964 assert((CondExpr || ConstevalOrNegatedConsteval) &&965 "If statement: missing condition");966 // Only call the CommaVisitor when not C89 due to differences in scope flags.967 if (CondExpr && (getLangOpts().C99 || getLangOpts().CPlusPlus) &&968 !Diags.isIgnored(diag::warn_comma_operator, CondExpr->getExprLoc()))969 CommaVisitor(*this).Visit(CondExpr);970 971 if (!ConstevalOrNegatedConsteval && !elseStmt)972 DiagnoseEmptyStmtBody(RParenLoc, thenStmt, diag::warn_empty_if_body);973 974 if (ConstevalOrNegatedConsteval ||975 StatementKind == IfStatementKind::Constexpr) {976 auto DiagnoseLikelihood = [&](const Stmt *S) {977 if (const Attr *A = Stmt::getLikelihoodAttr(S)) {978 Diags.Report(A->getLocation(),979 diag::warn_attribute_has_no_effect_on_compile_time_if)980 << A << ConstevalOrNegatedConsteval << A->getRange();981 Diags.Report(IfLoc,982 diag::note_attribute_has_no_effect_on_compile_time_if_here)983 << ConstevalOrNegatedConsteval984 << SourceRange(IfLoc, (ConstevalOrNegatedConsteval985 ? thenStmt->getBeginLoc()986 : LParenLoc)987 .getLocWithOffset(-1));988 }989 };990 DiagnoseLikelihood(thenStmt);991 DiagnoseLikelihood(elseStmt);992 } else {993 std::tuple<bool, const Attr *, const Attr *> LHC =994 Stmt::determineLikelihoodConflict(thenStmt, elseStmt);995 if (std::get<0>(LHC)) {996 const Attr *ThenAttr = std::get<1>(LHC);997 const Attr *ElseAttr = std::get<2>(LHC);998 Diags.Report(ThenAttr->getLocation(),999 diag::warn_attributes_likelihood_ifstmt_conflict)1000 << ThenAttr << ThenAttr->getRange();1001 Diags.Report(ElseAttr->getLocation(), diag::note_conflicting_attribute)1002 << ElseAttr << ElseAttr->getRange();1003 }1004 }1005 1006 if (ConstevalOrNegatedConsteval) {1007 bool Immediate = ExprEvalContexts.back().Context ==1008 ExpressionEvaluationContext::ImmediateFunctionContext;1009 if (CurContext->isFunctionOrMethod()) {1010 const auto *FD =1011 dyn_cast<FunctionDecl>(Decl::castFromDeclContext(CurContext));1012 if (FD && FD->isImmediateFunction())1013 Immediate = true;1014 }1015 if (isUnevaluatedContext() || Immediate)1016 Diags.Report(IfLoc, diag::warn_consteval_if_always_true) << Immediate;1017 }1018 1019 // OpenACC3.3 2.14.4:1020 // The update directive is executable. It must not appear in place of the1021 // statement following an 'if', 'while', 'do', 'switch', or 'label' in C or1022 // C++.1023 if (isa<OpenACCUpdateConstruct>(thenStmt)) {1024 Diag(thenStmt->getBeginLoc(), diag::err_acc_update_as_body) << /*if*/ 0;1025 thenStmt = new (Context) NullStmt(thenStmt->getBeginLoc());1026 }1027 1028 return BuildIfStmt(IfLoc, StatementKind, LParenLoc, InitStmt, Cond, RParenLoc,1029 thenStmt, ElseLoc, elseStmt);1030}1031 1032StmtResult Sema::BuildIfStmt(SourceLocation IfLoc,1033 IfStatementKind StatementKind,1034 SourceLocation LParenLoc, Stmt *InitStmt,1035 ConditionResult Cond, SourceLocation RParenLoc,1036 Stmt *thenStmt, SourceLocation ElseLoc,1037 Stmt *elseStmt) {1038 if (Cond.isInvalid())1039 return StmtError();1040 1041 if (StatementKind != IfStatementKind::Ordinary ||1042 isa<ObjCAvailabilityCheckExpr>(Cond.get().second))1043 setFunctionHasBranchProtectedScope();1044 1045 return IfStmt::Create(Context, IfLoc, StatementKind, InitStmt,1046 Cond.get().first, Cond.get().second, LParenLoc,1047 RParenLoc, thenStmt, ElseLoc, elseStmt);1048}1049 1050namespace {1051 struct CaseCompareFunctor {1052 bool operator()(const std::pair<llvm::APSInt, CaseStmt*> &LHS,1053 const llvm::APSInt &RHS) {1054 return LHS.first < RHS;1055 }1056 bool operator()(const std::pair<llvm::APSInt, CaseStmt*> &LHS,1057 const std::pair<llvm::APSInt, CaseStmt*> &RHS) {1058 return LHS.first < RHS.first;1059 }1060 bool operator()(const llvm::APSInt &LHS,1061 const std::pair<llvm::APSInt, CaseStmt*> &RHS) {1062 return LHS < RHS.first;1063 }1064 };1065}1066 1067/// CmpCaseVals - Comparison predicate for sorting case values.1068///1069static bool CmpCaseVals(const std::pair<llvm::APSInt, CaseStmt*>& lhs,1070 const std::pair<llvm::APSInt, CaseStmt*>& rhs) {1071 if (lhs.first < rhs.first)1072 return true;1073 1074 if (lhs.first == rhs.first &&1075 lhs.second->getCaseLoc() < rhs.second->getCaseLoc())1076 return true;1077 return false;1078}1079 1080/// CmpEnumVals - Comparison predicate for sorting enumeration values.1081///1082static bool CmpEnumVals(const std::pair<llvm::APSInt, EnumConstantDecl*>& lhs,1083 const std::pair<llvm::APSInt, EnumConstantDecl*>& rhs)1084{1085 return lhs.first < rhs.first;1086}1087 1088/// EqEnumVals - Comparison preficate for uniqing enumeration values.1089///1090static bool EqEnumVals(const std::pair<llvm::APSInt, EnumConstantDecl*>& lhs,1091 const std::pair<llvm::APSInt, EnumConstantDecl*>& rhs)1092{1093 return lhs.first == rhs.first;1094}1095 1096/// GetTypeBeforeIntegralPromotion - Returns the pre-promotion type of1097/// potentially integral-promoted expression @p expr.1098static QualType GetTypeBeforeIntegralPromotion(const Expr *&E) {1099 if (const auto *FE = dyn_cast<FullExpr>(E))1100 E = FE->getSubExpr();1101 while (const auto *ImpCast = dyn_cast<ImplicitCastExpr>(E)) {1102 if (ImpCast->getCastKind() != CK_IntegralCast) break;1103 E = ImpCast->getSubExpr();1104 }1105 return E->getType();1106}1107 1108ExprResult Sema::CheckSwitchCondition(SourceLocation SwitchLoc, Expr *Cond) {1109 class SwitchConvertDiagnoser : public ICEConvertDiagnoser {1110 Expr *Cond;1111 1112 public:1113 SwitchConvertDiagnoser(Expr *Cond)1114 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/true, false, true),1115 Cond(Cond) {}1116 1117 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc,1118 QualType T) override {1119 return S.Diag(Loc, diag::err_typecheck_statement_requires_integer) << T;1120 }1121 1122 SemaDiagnosticBuilder diagnoseIncomplete(1123 Sema &S, SourceLocation Loc, QualType T) override {1124 return S.Diag(Loc, diag::err_switch_incomplete_class_type)1125 << T << Cond->getSourceRange();1126 }1127 1128 SemaDiagnosticBuilder diagnoseExplicitConv(1129 Sema &S, SourceLocation Loc, QualType T, QualType ConvTy) override {1130 return S.Diag(Loc, diag::err_switch_explicit_conversion) << T << ConvTy;1131 }1132 1133 SemaDiagnosticBuilder noteExplicitConv(1134 Sema &S, CXXConversionDecl *Conv, QualType ConvTy) override {1135 return S.Diag(Conv->getLocation(), diag::note_switch_conversion)1136 << ConvTy->isEnumeralType() << ConvTy;1137 }1138 1139 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc,1140 QualType T) override {1141 return S.Diag(Loc, diag::err_switch_multiple_conversions) << T;1142 }1143 1144 SemaDiagnosticBuilder noteAmbiguous(1145 Sema &S, CXXConversionDecl *Conv, QualType ConvTy) override {1146 return S.Diag(Conv->getLocation(), diag::note_switch_conversion)1147 << ConvTy->isEnumeralType() << ConvTy;1148 }1149 1150 SemaDiagnosticBuilder diagnoseConversion(1151 Sema &S, SourceLocation Loc, QualType T, QualType ConvTy) override {1152 llvm_unreachable("conversion functions are permitted");1153 }1154 } SwitchDiagnoser(Cond);1155 1156 ExprResult CondResult =1157 PerformContextualImplicitConversion(SwitchLoc, Cond, SwitchDiagnoser);1158 if (CondResult.isInvalid())1159 return ExprError();1160 1161 // FIXME: PerformContextualImplicitConversion doesn't always tell us if it1162 // failed and produced a diagnostic.1163 Cond = CondResult.get();1164 if (!Cond->isTypeDependent() &&1165 !Cond->getType()->isIntegralOrEnumerationType())1166 return ExprError();1167 1168 // C99 6.8.4.2p5 - Integer promotions are performed on the controlling expr.1169 return UsualUnaryConversions(Cond);1170}1171 1172StmtResult Sema::ActOnStartOfSwitchStmt(SourceLocation SwitchLoc,1173 SourceLocation LParenLoc,1174 Stmt *InitStmt, ConditionResult Cond,1175 SourceLocation RParenLoc) {1176 Expr *CondExpr = Cond.get().second;1177 assert((Cond.isInvalid() || CondExpr) && "switch with no condition");1178 1179 if (CondExpr && !CondExpr->isTypeDependent()) {1180 // We have already converted the expression to an integral or enumeration1181 // type, when we parsed the switch condition. There are cases where we don't1182 // have an appropriate type, e.g. a typo-expr Cond was corrected to an1183 // inappropriate-type expr, we just return an error.1184 if (!CondExpr->getType()->isIntegralOrEnumerationType())1185 return StmtError();1186 if (CondExpr->isKnownToHaveBooleanValue()) {1187 // switch(bool_expr) {...} is often a programmer error, e.g.1188 // switch(n && mask) { ... } // Doh - should be "n & mask".1189 // One can always use an if statement instead of switch(bool_expr).1190 Diag(SwitchLoc, diag::warn_bool_switch_condition)1191 << CondExpr->getSourceRange();1192 }1193 }1194 1195 setFunctionHasBranchIntoScope();1196 1197 auto *SS = SwitchStmt::Create(Context, InitStmt, Cond.get().first, CondExpr,1198 LParenLoc, RParenLoc);1199 getCurFunction()->SwitchStack.push_back(1200 FunctionScopeInfo::SwitchInfo(SS, false));1201 return SS;1202}1203 1204static void AdjustAPSInt(llvm::APSInt &Val, unsigned BitWidth, bool IsSigned) {1205 Val = Val.extOrTrunc(BitWidth);1206 Val.setIsSigned(IsSigned);1207}1208 1209/// Check the specified case value is in range for the given unpromoted switch1210/// type.1211static void checkCaseValue(Sema &S, SourceLocation Loc, const llvm::APSInt &Val,1212 unsigned UnpromotedWidth, bool UnpromotedSign) {1213 // In C++11 onwards, this is checked by the language rules.1214 if (S.getLangOpts().CPlusPlus11)1215 return;1216 1217 // If the case value was signed and negative and the switch expression is1218 // unsigned, don't bother to warn: this is implementation-defined behavior.1219 // FIXME: Introduce a second, default-ignored warning for this case?1220 if (UnpromotedWidth < Val.getBitWidth()) {1221 llvm::APSInt ConvVal(Val);1222 AdjustAPSInt(ConvVal, UnpromotedWidth, UnpromotedSign);1223 AdjustAPSInt(ConvVal, Val.getBitWidth(), Val.isSigned());1224 // FIXME: Use different diagnostics for overflow in conversion to promoted1225 // type versus "switch expression cannot have this value". Use proper1226 // IntRange checking rather than just looking at the unpromoted type here.1227 if (ConvVal != Val)1228 S.Diag(Loc, diag::warn_case_value_overflow) << toString(Val, 10)1229 << toString(ConvVal, 10);1230 }1231}1232 1233typedef SmallVector<std::pair<llvm::APSInt, EnumConstantDecl*>, 64> EnumValsTy;1234 1235/// Returns true if we should emit a diagnostic about this case expression not1236/// being a part of the enum used in the switch controlling expression.1237static bool ShouldDiagnoseSwitchCaseNotInEnum(const Sema &S,1238 const EnumDecl *ED,1239 const Expr *CaseExpr,1240 EnumValsTy::iterator &EI,1241 EnumValsTy::iterator &EIEnd,1242 const llvm::APSInt &Val) {1243 if (!ED->isClosed())1244 return false;1245 1246 if (const DeclRefExpr *DRE =1247 dyn_cast<DeclRefExpr>(CaseExpr->IgnoreParenImpCasts())) {1248 if (const VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl())) {1249 QualType VarType = VD->getType();1250 CanQualType EnumType = S.Context.getCanonicalTagType(ED);1251 if (VD->hasGlobalStorage() && VarType.isConstQualified() &&1252 S.Context.hasSameUnqualifiedType(EnumType, VarType))1253 return false;1254 }1255 }1256 1257 if (ED->hasAttr<FlagEnumAttr>())1258 return !S.IsValueInFlagEnum(ED, Val, false);1259 1260 while (EI != EIEnd && EI->first < Val)1261 EI++;1262 1263 if (EI != EIEnd && EI->first == Val)1264 return false;1265 1266 return true;1267}1268 1269static void checkEnumTypesInSwitchStmt(Sema &S, const Expr *Cond,1270 const Expr *Case) {1271 QualType CondType = Cond->getType();1272 QualType CaseType = Case->getType();1273 1274 const EnumType *CondEnumType = CondType->getAsCanonical<EnumType>();1275 const EnumType *CaseEnumType = CaseType->getAsCanonical<EnumType>();1276 if (!CondEnumType || !CaseEnumType)1277 return;1278 1279 // Ignore anonymous enums.1280 if (!CondEnumType->getDecl()->getIdentifier() &&1281 !CondEnumType->getDecl()->getTypedefNameForAnonDecl())1282 return;1283 if (!CaseEnumType->getDecl()->getIdentifier() &&1284 !CaseEnumType->getDecl()->getTypedefNameForAnonDecl())1285 return;1286 1287 if (S.Context.hasSameUnqualifiedType(CondType, CaseType))1288 return;1289 1290 S.Diag(Case->getExprLoc(), diag::warn_comparison_of_mixed_enum_types_switch)1291 << CondType << CaseType << Cond->getSourceRange()1292 << Case->getSourceRange();1293}1294 1295StmtResult1296Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch,1297 Stmt *BodyStmt) {1298 SwitchStmt *SS = cast<SwitchStmt>(Switch);1299 bool CaseListIsIncomplete = getCurFunction()->SwitchStack.back().getInt();1300 assert(SS == getCurFunction()->SwitchStack.back().getPointer() &&1301 "switch stack missing push/pop!");1302 1303 getCurFunction()->SwitchStack.pop_back();1304 1305 if (!BodyStmt) return StmtError();1306 1307 // OpenACC3.3 2.14.4:1308 // The update directive is executable. It must not appear in place of the1309 // statement following an 'if', 'while', 'do', 'switch', or 'label' in C or1310 // C++.1311 if (isa<OpenACCUpdateConstruct>(BodyStmt)) {1312 Diag(BodyStmt->getBeginLoc(), diag::err_acc_update_as_body) << /*switch*/ 3;1313 BodyStmt = new (Context) NullStmt(BodyStmt->getBeginLoc());1314 }1315 1316 SS->setBody(BodyStmt, SwitchLoc);1317 1318 Expr *CondExpr = SS->getCond();1319 if (!CondExpr) return StmtError();1320 1321 QualType CondType = CondExpr->getType();1322 1323 // C++ 6.4.2.p2:1324 // Integral promotions are performed (on the switch condition).1325 //1326 // A case value unrepresentable by the original switch condition1327 // type (before the promotion) doesn't make sense, even when it can1328 // be represented by the promoted type. Therefore we need to find1329 // the pre-promotion type of the switch condition.1330 const Expr *CondExprBeforePromotion = CondExpr;1331 QualType CondTypeBeforePromotion =1332 GetTypeBeforeIntegralPromotion(CondExprBeforePromotion);1333 1334 // Get the bitwidth of the switched-on value after promotions. We must1335 // convert the integer case values to this width before comparison.1336 bool HasDependentValue1337 = CondExpr->isTypeDependent() || CondExpr->isValueDependent();1338 unsigned CondWidth = HasDependentValue ? 0 : Context.getIntWidth(CondType);1339 bool CondIsSigned = CondType->isSignedIntegerOrEnumerationType();1340 1341 // Get the width and signedness that the condition might actually have, for1342 // warning purposes.1343 // FIXME: Grab an IntRange for the condition rather than using the unpromoted1344 // type.1345 unsigned CondWidthBeforePromotion1346 = HasDependentValue ? 0 : Context.getIntWidth(CondTypeBeforePromotion);1347 bool CondIsSignedBeforePromotion1348 = CondTypeBeforePromotion->isSignedIntegerOrEnumerationType();1349 1350 // Accumulate all of the case values in a vector so that we can sort them1351 // and detect duplicates. This vector contains the APInt for the case after1352 // it has been converted to the condition type.1353 typedef SmallVector<std::pair<llvm::APSInt, CaseStmt*>, 64> CaseValsTy;1354 CaseValsTy CaseVals;1355 1356 // Keep track of any GNU case ranges we see. The APSInt is the low value.1357 typedef std::vector<std::pair<llvm::APSInt, CaseStmt*> > CaseRangesTy;1358 CaseRangesTy CaseRanges;1359 1360 DefaultStmt *TheDefaultStmt = nullptr;1361 1362 bool CaseListIsErroneous = false;1363 1364 // FIXME: We'd better diagnose missing or duplicate default labels even1365 // in the dependent case. Because default labels themselves are never1366 // dependent.1367 for (SwitchCase *SC = SS->getSwitchCaseList(); SC && !HasDependentValue;1368 SC = SC->getNextSwitchCase()) {1369 1370 if (DefaultStmt *DS = dyn_cast<DefaultStmt>(SC)) {1371 if (TheDefaultStmt) {1372 Diag(DS->getDefaultLoc(), diag::err_multiple_default_labels_defined);1373 Diag(TheDefaultStmt->getDefaultLoc(), diag::note_duplicate_case_prev);1374 1375 // FIXME: Remove the default statement from the switch block so that1376 // we'll return a valid AST. This requires recursing down the AST and1377 // finding it, not something we are set up to do right now. For now,1378 // just lop the entire switch stmt out of the AST.1379 CaseListIsErroneous = true;1380 }1381 TheDefaultStmt = DS;1382 1383 } else {1384 CaseStmt *CS = cast<CaseStmt>(SC);1385 1386 Expr *Lo = CS->getLHS();1387 1388 if (Lo->isValueDependent()) {1389 HasDependentValue = true;1390 break;1391 }1392 1393 // We already verified that the expression has a constant value;1394 // get that value (prior to conversions).1395 const Expr *LoBeforePromotion = Lo;1396 GetTypeBeforeIntegralPromotion(LoBeforePromotion);1397 llvm::APSInt LoVal = LoBeforePromotion->EvaluateKnownConstInt(Context);1398 1399 // Check the unconverted value is within the range of possible values of1400 // the switch expression.1401 checkCaseValue(*this, Lo->getBeginLoc(), LoVal, CondWidthBeforePromotion,1402 CondIsSignedBeforePromotion);1403 1404 // FIXME: This duplicates the check performed for warn_not_in_enum below.1405 checkEnumTypesInSwitchStmt(*this, CondExprBeforePromotion,1406 LoBeforePromotion);1407 1408 // Convert the value to the same width/sign as the condition.1409 AdjustAPSInt(LoVal, CondWidth, CondIsSigned);1410 1411 // If this is a case range, remember it in CaseRanges, otherwise CaseVals.1412 if (CS->getRHS()) {1413 if (CS->getRHS()->isValueDependent()) {1414 HasDependentValue = true;1415 break;1416 }1417 CaseRanges.push_back(std::make_pair(LoVal, CS));1418 } else1419 CaseVals.push_back(std::make_pair(LoVal, CS));1420 }1421 }1422 1423 if (!HasDependentValue) {1424 // If we don't have a default statement, check whether the1425 // condition is constant.1426 llvm::APSInt ConstantCondValue;1427 bool HasConstantCond = false;1428 if (!TheDefaultStmt) {1429 Expr::EvalResult Result;1430 HasConstantCond = CondExpr->EvaluateAsInt(Result, Context,1431 Expr::SE_AllowSideEffects);1432 if (Result.Val.isInt())1433 ConstantCondValue = Result.Val.getInt();1434 assert(!HasConstantCond ||1435 (ConstantCondValue.getBitWidth() == CondWidth &&1436 ConstantCondValue.isSigned() == CondIsSigned));1437 Diag(SwitchLoc, diag::warn_switch_default);1438 }1439 bool ShouldCheckConstantCond = HasConstantCond;1440 1441 // Sort all the scalar case values so we can easily detect duplicates.1442 llvm::stable_sort(CaseVals, CmpCaseVals);1443 1444 if (!CaseVals.empty()) {1445 for (unsigned i = 0, e = CaseVals.size(); i != e; ++i) {1446 if (ShouldCheckConstantCond &&1447 CaseVals[i].first == ConstantCondValue)1448 ShouldCheckConstantCond = false;1449 1450 if (i != 0 && CaseVals[i].first == CaseVals[i-1].first) {1451 // If we have a duplicate, report it.1452 // First, determine if either case value has a name1453 StringRef PrevString, CurrString;1454 Expr *PrevCase = CaseVals[i-1].second->getLHS()->IgnoreParenCasts();1455 Expr *CurrCase = CaseVals[i].second->getLHS()->IgnoreParenCasts();1456 if (DeclRefExpr *DeclRef = dyn_cast<DeclRefExpr>(PrevCase)) {1457 PrevString = DeclRef->getDecl()->getName();1458 }1459 if (DeclRefExpr *DeclRef = dyn_cast<DeclRefExpr>(CurrCase)) {1460 CurrString = DeclRef->getDecl()->getName();1461 }1462 SmallString<16> CaseValStr;1463 CaseVals[i-1].first.toString(CaseValStr);1464 1465 if (PrevString == CurrString)1466 Diag(CaseVals[i].second->getLHS()->getBeginLoc(),1467 diag::err_duplicate_case)1468 << (PrevString.empty() ? CaseValStr.str() : PrevString);1469 else1470 Diag(CaseVals[i].second->getLHS()->getBeginLoc(),1471 diag::err_duplicate_case_differing_expr)1472 << (PrevString.empty() ? CaseValStr.str() : PrevString)1473 << (CurrString.empty() ? CaseValStr.str() : CurrString)1474 << CaseValStr;1475 1476 Diag(CaseVals[i - 1].second->getLHS()->getBeginLoc(),1477 diag::note_duplicate_case_prev);1478 // FIXME: We really want to remove the bogus case stmt from the1479 // substmt, but we have no way to do this right now.1480 CaseListIsErroneous = true;1481 }1482 }1483 }1484 1485 // Detect duplicate case ranges, which usually don't exist at all in1486 // the first place.1487 if (!CaseRanges.empty()) {1488 // Sort all the case ranges by their low value so we can easily detect1489 // overlaps between ranges.1490 llvm::stable_sort(CaseRanges);1491 1492 // Scan the ranges, computing the high values and removing empty ranges.1493 std::vector<llvm::APSInt> HiVals;1494 for (unsigned i = 0, e = CaseRanges.size(); i != e; ++i) {1495 llvm::APSInt &LoVal = CaseRanges[i].first;1496 CaseStmt *CR = CaseRanges[i].second;1497 Expr *Hi = CR->getRHS();1498 1499 const Expr *HiBeforePromotion = Hi;1500 GetTypeBeforeIntegralPromotion(HiBeforePromotion);1501 llvm::APSInt HiVal = HiBeforePromotion->EvaluateKnownConstInt(Context);1502 1503 // Check the unconverted value is within the range of possible values of1504 // the switch expression.1505 checkCaseValue(*this, Hi->getBeginLoc(), HiVal,1506 CondWidthBeforePromotion, CondIsSignedBeforePromotion);1507 1508 // Convert the value to the same width/sign as the condition.1509 AdjustAPSInt(HiVal, CondWidth, CondIsSigned);1510 1511 // If the low value is bigger than the high value, the case is empty.1512 if (LoVal > HiVal) {1513 Diag(CR->getLHS()->getBeginLoc(), diag::warn_case_empty_range)1514 << SourceRange(CR->getLHS()->getBeginLoc(), Hi->getEndLoc());1515 CaseRanges.erase(CaseRanges.begin()+i);1516 --i;1517 --e;1518 continue;1519 }1520 1521 if (ShouldCheckConstantCond &&1522 LoVal <= ConstantCondValue &&1523 ConstantCondValue <= HiVal)1524 ShouldCheckConstantCond = false;1525 1526 HiVals.push_back(HiVal);1527 }1528 1529 // Rescan the ranges, looking for overlap with singleton values and other1530 // ranges. Since the range list is sorted, we only need to compare case1531 // ranges with their neighbors.1532 for (unsigned i = 0, e = CaseRanges.size(); i != e; ++i) {1533 llvm::APSInt &CRLo = CaseRanges[i].first;1534 llvm::APSInt &CRHi = HiVals[i];1535 CaseStmt *CR = CaseRanges[i].second;1536 1537 // Check to see whether the case range overlaps with any1538 // singleton cases.1539 CaseStmt *OverlapStmt = nullptr;1540 llvm::APSInt OverlapVal(32);1541 1542 // Find the smallest value >= the lower bound. If I is in the1543 // case range, then we have overlap.1544 CaseValsTy::iterator I =1545 llvm::lower_bound(CaseVals, CRLo, CaseCompareFunctor());1546 if (I != CaseVals.end() && I->first < CRHi) {1547 OverlapVal = I->first; // Found overlap with scalar.1548 OverlapStmt = I->second;1549 }1550 1551 // Find the smallest value bigger than the upper bound.1552 I = std::upper_bound(I, CaseVals.end(), CRHi, CaseCompareFunctor());1553 if (I != CaseVals.begin() && (I-1)->first >= CRLo) {1554 OverlapVal = (I-1)->first; // Found overlap with scalar.1555 OverlapStmt = (I-1)->second;1556 }1557 1558 // Check to see if this case stmt overlaps with the subsequent1559 // case range.1560 if (i && CRLo <= HiVals[i-1]) {1561 OverlapVal = HiVals[i-1]; // Found overlap with range.1562 OverlapStmt = CaseRanges[i-1].second;1563 }1564 1565 if (OverlapStmt) {1566 // If we have a duplicate, report it.1567 Diag(CR->getLHS()->getBeginLoc(), diag::err_duplicate_case)1568 << toString(OverlapVal, 10);1569 Diag(OverlapStmt->getLHS()->getBeginLoc(),1570 diag::note_duplicate_case_prev);1571 // FIXME: We really want to remove the bogus case stmt from the1572 // substmt, but we have no way to do this right now.1573 CaseListIsErroneous = true;1574 }1575 }1576 }1577 1578 // Complain if we have a constant condition and we didn't find a match.1579 if (!CaseListIsErroneous && !CaseListIsIncomplete &&1580 ShouldCheckConstantCond) {1581 // TODO: it would be nice if we printed enums as enums, chars as1582 // chars, etc.1583 Diag(CondExpr->getExprLoc(), diag::warn_missing_case_for_condition)1584 << toString(ConstantCondValue, 10)1585 << CondExpr->getSourceRange();1586 }1587 1588 // Check to see if switch is over an Enum and handles all of its1589 // values. We only issue a warning if there is not 'default:', but1590 // we still do the analysis to preserve this information in the AST1591 // (which can be used by flow-based analyes).1592 //1593 // If switch has default case, then ignore it.1594 if (!CaseListIsErroneous && !CaseListIsIncomplete && !HasConstantCond &&1595 CondTypeBeforePromotion->isEnumeralType()) {1596 const auto *ED = CondTypeBeforePromotion->castAsEnumDecl();1597 if (!ED->isCompleteDefinition() || ED->enumerators().empty())1598 goto enum_out;1599 1600 EnumValsTy EnumVals;1601 1602 // Gather all enum values, set their type and sort them,1603 // allowing easier comparison with CaseVals.1604 for (auto *EDI : ED->enumerators()) {1605 llvm::APSInt Val = EDI->getInitVal();1606 AdjustAPSInt(Val, CondWidth, CondIsSigned);1607 EnumVals.push_back(std::make_pair(Val, EDI));1608 }1609 llvm::stable_sort(EnumVals, CmpEnumVals);1610 auto EI = EnumVals.begin(), EIEnd = llvm::unique(EnumVals, EqEnumVals);1611 1612 // See which case values aren't in enum.1613 for (CaseValsTy::const_iterator CI = CaseVals.begin();1614 CI != CaseVals.end(); CI++) {1615 Expr *CaseExpr = CI->second->getLHS();1616 if (ShouldDiagnoseSwitchCaseNotInEnum(*this, ED, CaseExpr, EI, EIEnd,1617 CI->first))1618 Diag(CaseExpr->getExprLoc(), diag::warn_not_in_enum)1619 << CondTypeBeforePromotion;1620 }1621 1622 // See which of case ranges aren't in enum1623 EI = EnumVals.begin();1624 for (CaseRangesTy::const_iterator RI = CaseRanges.begin();1625 RI != CaseRanges.end(); RI++) {1626 Expr *CaseExpr = RI->second->getLHS();1627 if (ShouldDiagnoseSwitchCaseNotInEnum(*this, ED, CaseExpr, EI, EIEnd,1628 RI->first))1629 Diag(CaseExpr->getExprLoc(), diag::warn_not_in_enum)1630 << CondTypeBeforePromotion;1631 1632 llvm::APSInt Hi =1633 RI->second->getRHS()->EvaluateKnownConstInt(Context);1634 AdjustAPSInt(Hi, CondWidth, CondIsSigned);1635 1636 CaseExpr = RI->second->getRHS();1637 if (ShouldDiagnoseSwitchCaseNotInEnum(*this, ED, CaseExpr, EI, EIEnd,1638 Hi))1639 Diag(CaseExpr->getExprLoc(), diag::warn_not_in_enum)1640 << CondTypeBeforePromotion;1641 }1642 1643 // Check which enum vals aren't in switch1644 auto CI = CaseVals.begin();1645 auto RI = CaseRanges.begin();1646 bool hasCasesNotInSwitch = false;1647 1648 SmallVector<DeclarationName,8> UnhandledNames;1649 1650 for (EI = EnumVals.begin(); EI != EIEnd; EI++) {1651 // Don't warn about omitted unavailable EnumConstantDecls.1652 switch (EI->second->getAvailability()) {1653 case AR_Deprecated:1654 // Deprecated enumerators need to be handled: they may be deprecated,1655 // but can still occur.1656 break;1657 1658 case AR_Unavailable:1659 // Omitting an unavailable enumerator is ok; it should never occur.1660 continue;1661 1662 case AR_NotYetIntroduced:1663 // Partially available enum constants should be present. Note that we1664 // suppress -Wunguarded-availability diagnostics for such uses.1665 case AR_Available:1666 break;1667 }1668 1669 if (EI->second->hasAttr<UnusedAttr>())1670 continue;1671 1672 // Drop unneeded case values1673 while (CI != CaseVals.end() && CI->first < EI->first)1674 CI++;1675 1676 if (CI != CaseVals.end() && CI->first == EI->first)1677 continue;1678 1679 // Drop unneeded case ranges1680 for (; RI != CaseRanges.end(); RI++) {1681 llvm::APSInt Hi =1682 RI->second->getRHS()->EvaluateKnownConstInt(Context);1683 AdjustAPSInt(Hi, CondWidth, CondIsSigned);1684 if (EI->first <= Hi)1685 break;1686 }1687 1688 if (RI == CaseRanges.end() || EI->first < RI->first) {1689 hasCasesNotInSwitch = true;1690 UnhandledNames.push_back(EI->second->getDeclName());1691 }1692 }1693 1694 if (TheDefaultStmt && UnhandledNames.empty() && ED->isClosedNonFlag())1695 Diag(TheDefaultStmt->getDefaultLoc(), diag::warn_unreachable_default);1696 1697 // Produce a nice diagnostic if multiple values aren't handled.1698 if (!UnhandledNames.empty()) {1699 auto DB = Diag(CondExpr->getExprLoc(), TheDefaultStmt1700 ? diag::warn_def_missing_case1701 : diag::warn_missing_case)1702 << CondExpr->getSourceRange() << (int)UnhandledNames.size();1703 1704 for (size_t I = 0, E = std::min(UnhandledNames.size(), (size_t)3);1705 I != E; ++I)1706 DB << UnhandledNames[I];1707 }1708 1709 if (!hasCasesNotInSwitch)1710 SS->setAllEnumCasesCovered();1711 }1712 enum_out:;1713 }1714 1715 if (BodyStmt)1716 DiagnoseEmptyStmtBody(CondExpr->getEndLoc(), BodyStmt,1717 diag::warn_empty_switch_body);1718 1719 // FIXME: If the case list was broken is some way, we don't have a good system1720 // to patch it up. Instead, just return the whole substmt as broken.1721 if (CaseListIsErroneous)1722 return StmtError();1723 1724 return SS;1725}1726 1727void1728Sema::DiagnoseAssignmentEnum(QualType DstType, QualType SrcType,1729 Expr *SrcExpr) {1730 1731 if (!DstType->isEnumeralType())1732 return;1733 1734 if (!SrcType->isIntegerType() ||1735 Context.hasSameUnqualifiedType(SrcType, DstType))1736 return;1737 1738 if (SrcExpr->isTypeDependent() || SrcExpr->isValueDependent())1739 return;1740 1741 const auto *ED = DstType->castAsEnumDecl();1742 if (!ED->isClosed())1743 return;1744 1745 if (Diags.isIgnored(diag::warn_not_in_enum_assignment, SrcExpr->getExprLoc()))1746 return;1747 1748 std::optional<llvm::APSInt> RHSVal = SrcExpr->getIntegerConstantExpr(Context);1749 if (!RHSVal)1750 return;1751 1752 // Get the bitwidth of the enum value before promotions.1753 unsigned DstWidth = Context.getIntWidth(DstType);1754 bool DstIsSigned = DstType->isSignedIntegerOrEnumerationType();1755 AdjustAPSInt(*RHSVal, DstWidth, DstIsSigned);1756 1757 if (ED->hasAttr<FlagEnumAttr>()) {1758 if (!IsValueInFlagEnum(ED, *RHSVal, /*AllowMask=*/true))1759 Diag(SrcExpr->getExprLoc(), diag::warn_not_in_enum_assignment)1760 << DstType.getUnqualifiedType();1761 return;1762 }1763 1764 typedef SmallVector<std::pair<llvm::APSInt, EnumConstantDecl *>, 64>1765 EnumValsTy;1766 EnumValsTy EnumVals;1767 1768 // Gather all enum values, set their type and sort them,1769 // allowing easier comparison with rhs constant.1770 for (auto *EDI : ED->enumerators()) {1771 llvm::APSInt Val = EDI->getInitVal();1772 AdjustAPSInt(Val, DstWidth, DstIsSigned);1773 EnumVals.emplace_back(Val, EDI);1774 }1775 if (EnumVals.empty())1776 return;1777 llvm::stable_sort(EnumVals, CmpEnumVals);1778 EnumValsTy::iterator EIend = llvm::unique(EnumVals, EqEnumVals);1779 1780 // See which values aren't in the enum.1781 EnumValsTy::const_iterator EI = EnumVals.begin();1782 while (EI != EIend && EI->first < *RHSVal)1783 EI++;1784 if (EI == EIend || EI->first != *RHSVal) {1785 Diag(SrcExpr->getExprLoc(), diag::warn_not_in_enum_assignment)1786 << DstType.getUnqualifiedType();1787 }1788}1789 1790StmtResult Sema::ActOnWhileStmt(SourceLocation WhileLoc,1791 SourceLocation LParenLoc, ConditionResult Cond,1792 SourceLocation RParenLoc, Stmt *Body) {1793 if (Cond.isInvalid())1794 return StmtError();1795 1796 auto CondVal = Cond.get();1797 CheckBreakContinueBinding(CondVal.second);1798 1799 if (CondVal.second &&1800 !Diags.isIgnored(diag::warn_comma_operator, CondVal.second->getExprLoc()))1801 CommaVisitor(*this).Visit(CondVal.second);1802 1803 // OpenACC3.3 2.14.4:1804 // The update directive is executable. It must not appear in place of the1805 // statement following an 'if', 'while', 'do', 'switch', or 'label' in C or1806 // C++.1807 if (isa<OpenACCUpdateConstruct>(Body)) {1808 Diag(Body->getBeginLoc(), diag::err_acc_update_as_body) << /*while*/ 1;1809 Body = new (Context) NullStmt(Body->getBeginLoc());1810 }1811 1812 if (isa<NullStmt>(Body))1813 getCurCompoundScope().setHasEmptyLoopBodies();1814 1815 return WhileStmt::Create(Context, CondVal.first, CondVal.second, Body,1816 WhileLoc, LParenLoc, RParenLoc);1817}1818 1819StmtResult1820Sema::ActOnDoStmt(SourceLocation DoLoc, Stmt *Body,1821 SourceLocation WhileLoc, SourceLocation CondLParen,1822 Expr *Cond, SourceLocation CondRParen) {1823 assert(Cond && "ActOnDoStmt(): missing expression");1824 1825 CheckBreakContinueBinding(Cond);1826 ExprResult CondResult = CheckBooleanCondition(DoLoc, Cond);1827 if (CondResult.isInvalid())1828 return StmtError();1829 Cond = CondResult.get();1830 1831 CondResult = ActOnFinishFullExpr(Cond, DoLoc, /*DiscardedValue*/ false);1832 if (CondResult.isInvalid())1833 return StmtError();1834 Cond = CondResult.get();1835 1836 // Only call the CommaVisitor for C89 due to differences in scope flags.1837 if (Cond && !getLangOpts().C99 && !getLangOpts().CPlusPlus &&1838 !Diags.isIgnored(diag::warn_comma_operator, Cond->getExprLoc()))1839 CommaVisitor(*this).Visit(Cond);1840 1841 // OpenACC3.3 2.14.4:1842 // The update directive is executable. It must not appear in place of the1843 // statement following an 'if', 'while', 'do', 'switch', or 'label' in C or1844 // C++.1845 if (isa<OpenACCUpdateConstruct>(Body)) {1846 Diag(Body->getBeginLoc(), diag::err_acc_update_as_body) << /*do*/ 2;1847 Body = new (Context) NullStmt(Body->getBeginLoc());1848 }1849 1850 return new (Context) DoStmt(Body, Cond, DoLoc, WhileLoc, CondRParen);1851}1852 1853namespace {1854 // Use SetVector since the diagnostic cares about the ordering of the Decl's.1855 using DeclSetVector = llvm::SmallSetVector<VarDecl *, 8>;1856 1857 // This visitor will traverse a conditional statement and store all1858 // the evaluated decls into a vector. Simple is set to true if none1859 // of the excluded constructs are used.1860 class DeclExtractor : public EvaluatedExprVisitor<DeclExtractor> {1861 DeclSetVector &Decls;1862 SmallVectorImpl<SourceRange> &Ranges;1863 bool Simple;1864 public:1865 typedef EvaluatedExprVisitor<DeclExtractor> Inherited;1866 1867 DeclExtractor(Sema &S, DeclSetVector &Decls,1868 SmallVectorImpl<SourceRange> &Ranges) :1869 Inherited(S.Context),1870 Decls(Decls),1871 Ranges(Ranges),1872 Simple(true) {}1873 1874 bool isSimple() { return Simple; }1875 1876 // Replaces the method in EvaluatedExprVisitor.1877 void VisitMemberExpr(MemberExpr* E) {1878 Simple = false;1879 }1880 1881 // Any Stmt not explicitly listed will cause the condition to be marked1882 // complex.1883 void VisitStmt(Stmt *S) { Simple = false; }1884 1885 void VisitBinaryOperator(BinaryOperator *E) {1886 Visit(E->getLHS());1887 Visit(E->getRHS());1888 }1889 1890 void VisitCastExpr(CastExpr *E) {1891 Visit(E->getSubExpr());1892 }1893 1894 void VisitUnaryOperator(UnaryOperator *E) {1895 // Skip checking conditionals with derefernces.1896 if (E->getOpcode() == UO_Deref)1897 Simple = false;1898 else1899 Visit(E->getSubExpr());1900 }1901 1902 void VisitConditionalOperator(ConditionalOperator *E) {1903 Visit(E->getCond());1904 Visit(E->getTrueExpr());1905 Visit(E->getFalseExpr());1906 }1907 1908 void VisitParenExpr(ParenExpr *E) {1909 Visit(E->getSubExpr());1910 }1911 1912 void VisitBinaryConditionalOperator(BinaryConditionalOperator *E) {1913 Visit(E->getOpaqueValue()->getSourceExpr());1914 Visit(E->getFalseExpr());1915 }1916 1917 void VisitIntegerLiteral(IntegerLiteral *E) { }1918 void VisitFloatingLiteral(FloatingLiteral *E) { }1919 void VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) { }1920 void VisitCharacterLiteral(CharacterLiteral *E) { }1921 void VisitGNUNullExpr(GNUNullExpr *E) { }1922 void VisitImaginaryLiteral(ImaginaryLiteral *E) { }1923 1924 void VisitDeclRefExpr(DeclRefExpr *E) {1925 VarDecl *VD = dyn_cast<VarDecl>(E->getDecl());1926 if (!VD) {1927 // Don't allow unhandled Decl types.1928 Simple = false;1929 return;1930 }1931 1932 Ranges.push_back(E->getSourceRange());1933 1934 Decls.insert(VD);1935 }1936 1937 }; // end class DeclExtractor1938 1939 // DeclMatcher checks to see if the decls are used in a non-evaluated1940 // context.1941 class DeclMatcher : public EvaluatedExprVisitor<DeclMatcher> {1942 DeclSetVector &Decls;1943 bool FoundDecl;1944 1945 public:1946 typedef EvaluatedExprVisitor<DeclMatcher> Inherited;1947 1948 DeclMatcher(Sema &S, DeclSetVector &Decls, Stmt *Statement) :1949 Inherited(S.Context), Decls(Decls), FoundDecl(false) {1950 if (!Statement) return;1951 1952 Visit(Statement);1953 }1954 1955 void VisitReturnStmt(ReturnStmt *S) {1956 FoundDecl = true;1957 }1958 1959 void VisitBreakStmt(BreakStmt *S) {1960 FoundDecl = true;1961 }1962 1963 void VisitGotoStmt(GotoStmt *S) {1964 FoundDecl = true;1965 }1966 1967 void VisitCastExpr(CastExpr *E) {1968 if (E->getCastKind() == CK_LValueToRValue)1969 CheckLValueToRValueCast(E->getSubExpr());1970 else1971 Visit(E->getSubExpr());1972 }1973 1974 void CheckLValueToRValueCast(Expr *E) {1975 E = E->IgnoreParenImpCasts();1976 1977 if (isa<DeclRefExpr>(E)) {1978 return;1979 }1980 1981 if (ConditionalOperator *CO = dyn_cast<ConditionalOperator>(E)) {1982 Visit(CO->getCond());1983 CheckLValueToRValueCast(CO->getTrueExpr());1984 CheckLValueToRValueCast(CO->getFalseExpr());1985 return;1986 }1987 1988 if (BinaryConditionalOperator *BCO =1989 dyn_cast<BinaryConditionalOperator>(E)) {1990 CheckLValueToRValueCast(BCO->getOpaqueValue()->getSourceExpr());1991 CheckLValueToRValueCast(BCO->getFalseExpr());1992 return;1993 }1994 1995 Visit(E);1996 }1997 1998 void VisitDeclRefExpr(DeclRefExpr *E) {1999 if (VarDecl *VD = dyn_cast<VarDecl>(E->getDecl()))2000 if (Decls.count(VD))2001 FoundDecl = true;2002 }2003 2004 void VisitPseudoObjectExpr(PseudoObjectExpr *POE) {2005 // Only need to visit the semantics for POE.2006 // SyntaticForm doesn't really use the Decal.2007 for (auto *S : POE->semantics()) {2008 if (auto *OVE = dyn_cast<OpaqueValueExpr>(S))2009 // Look past the OVE into the expression it binds.2010 Visit(OVE->getSourceExpr());2011 else2012 Visit(S);2013 }2014 }2015 2016 bool FoundDeclInUse() { return FoundDecl; }2017 2018 }; // end class DeclMatcher2019 2020 void CheckForLoopConditionalStatement(Sema &S, Expr *Second,2021 Expr *Third, Stmt *Body) {2022 // Condition is empty2023 if (!Second) return;2024 2025 if (S.Diags.isIgnored(diag::warn_variables_not_in_loop_body,2026 Second->getBeginLoc()))2027 return;2028 2029 PartialDiagnostic PDiag = S.PDiag(diag::warn_variables_not_in_loop_body);2030 DeclSetVector Decls;2031 SmallVector<SourceRange, 10> Ranges;2032 DeclExtractor DE(S, Decls, Ranges);2033 DE.Visit(Second);2034 2035 // Don't analyze complex conditionals.2036 if (!DE.isSimple()) return;2037 2038 // No decls found.2039 if (Decls.size() == 0) return;2040 2041 // Don't warn on volatile, static, or global variables.2042 for (auto *VD : Decls)2043 if (VD->getType().isVolatileQualified() || VD->hasGlobalStorage())2044 return;2045 2046 if (DeclMatcher(S, Decls, Second).FoundDeclInUse() ||2047 DeclMatcher(S, Decls, Third).FoundDeclInUse() ||2048 DeclMatcher(S, Decls, Body).FoundDeclInUse())2049 return;2050 2051 // Load decl names into diagnostic.2052 if (Decls.size() > 4) {2053 PDiag << 0;2054 } else {2055 PDiag << (unsigned)Decls.size();2056 for (auto *VD : Decls)2057 PDiag << VD->getDeclName();2058 }2059 2060 for (auto Range : Ranges)2061 PDiag << Range;2062 2063 S.Diag(Ranges.begin()->getBegin(), PDiag);2064 }2065 2066 // If Statement is an incemement or decrement, return true and sets the2067 // variables Increment and DRE.2068 bool ProcessIterationStmt(Sema &S, Stmt* Statement, bool &Increment,2069 DeclRefExpr *&DRE) {2070 if (auto Cleanups = dyn_cast<ExprWithCleanups>(Statement))2071 if (!Cleanups->cleanupsHaveSideEffects())2072 Statement = Cleanups->getSubExpr();2073 2074 if (UnaryOperator *UO = dyn_cast<UnaryOperator>(Statement)) {2075 switch (UO->getOpcode()) {2076 default: return false;2077 case UO_PostInc:2078 case UO_PreInc:2079 Increment = true;2080 break;2081 case UO_PostDec:2082 case UO_PreDec:2083 Increment = false;2084 break;2085 }2086 DRE = dyn_cast<DeclRefExpr>(UO->getSubExpr());2087 return DRE;2088 }2089 2090 if (CXXOperatorCallExpr *Call = dyn_cast<CXXOperatorCallExpr>(Statement)) {2091 FunctionDecl *FD = Call->getDirectCallee();2092 if (!FD || !FD->isOverloadedOperator()) return false;2093 switch (FD->getOverloadedOperator()) {2094 default: return false;2095 case OO_PlusPlus:2096 Increment = true;2097 break;2098 case OO_MinusMinus:2099 Increment = false;2100 break;2101 }2102 DRE = dyn_cast<DeclRefExpr>(Call->getArg(0));2103 return DRE;2104 }2105 2106 return false;2107 }2108 2109 // A visitor to determine if a continue or break statement is a2110 // subexpression.2111 class BreakContinueFinder : public ConstEvaluatedExprVisitor<BreakContinueFinder> {2112 SourceLocation BreakLoc;2113 SourceLocation ContinueLoc;2114 bool InSwitch = false;2115 2116 public:2117 BreakContinueFinder(Sema &S, const Stmt* Body) :2118 Inherited(S.Context) {2119 Visit(Body);2120 }2121 2122 typedef ConstEvaluatedExprVisitor<BreakContinueFinder> Inherited;2123 2124 void VisitContinueStmt(const ContinueStmt* E) {2125 ContinueLoc = E->getKwLoc();2126 }2127 2128 void VisitBreakStmt(const BreakStmt* E) {2129 if (!InSwitch)2130 BreakLoc = E->getKwLoc();2131 }2132 2133 void VisitSwitchStmt(const SwitchStmt* S) {2134 if (const Stmt *Init = S->getInit())2135 Visit(Init);2136 if (const Stmt *CondVar = S->getConditionVariableDeclStmt())2137 Visit(CondVar);2138 if (const Stmt *Cond = S->getCond())2139 Visit(Cond);2140 2141 // Don't return break statements from the body of a switch.2142 InSwitch = true;2143 if (const Stmt *Body = S->getBody())2144 Visit(Body);2145 InSwitch = false;2146 }2147 2148 void VisitForStmt(const ForStmt *S) {2149 // Only visit the init statement of a for loop; the body2150 // has a different break/continue scope.2151 if (const Stmt *Init = S->getInit())2152 Visit(Init);2153 }2154 2155 void VisitWhileStmt(const WhileStmt *) {2156 // Do nothing; the children of a while loop have a different2157 // break/continue scope.2158 }2159 2160 void VisitDoStmt(const DoStmt *) {2161 // Do nothing; the children of a while loop have a different2162 // break/continue scope.2163 }2164 2165 void VisitCXXForRangeStmt(const CXXForRangeStmt *S) {2166 // Only visit the initialization of a for loop; the body2167 // has a different break/continue scope.2168 if (const Stmt *Init = S->getInit())2169 Visit(Init);2170 if (const Stmt *Range = S->getRangeStmt())2171 Visit(Range);2172 if (const Stmt *Begin = S->getBeginStmt())2173 Visit(Begin);2174 if (const Stmt *End = S->getEndStmt())2175 Visit(End);2176 }2177 2178 void VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S) {2179 // Only visit the initialization of a for loop; the body2180 // has a different break/continue scope.2181 if (const Stmt *Element = S->getElement())2182 Visit(Element);2183 if (const Stmt *Collection = S->getCollection())2184 Visit(Collection);2185 }2186 2187 bool ContinueFound() { return ContinueLoc.isValid(); }2188 bool BreakFound() { return BreakLoc.isValid(); }2189 SourceLocation GetContinueLoc() { return ContinueLoc; }2190 SourceLocation GetBreakLoc() { return BreakLoc; }2191 2192 }; // end class BreakContinueFinder2193 2194 // Emit a warning when a loop increment/decrement appears twice per loop2195 // iteration. The conditions which trigger this warning are:2196 // 1) The last statement in the loop body and the third expression in the2197 // for loop are both increment or both decrement of the same variable2198 // 2) No continue statements in the loop body.2199 void CheckForRedundantIteration(Sema &S, Expr *Third, Stmt *Body) {2200 // Return when there is nothing to check.2201 if (!Body || !Third) return;2202 2203 // Get the last statement from the loop body.2204 CompoundStmt *CS = dyn_cast<CompoundStmt>(Body);2205 if (!CS || CS->body_empty()) return;2206 Stmt *LastStmt = CS->body_back();2207 if (!LastStmt) return;2208 2209 if (S.Diags.isIgnored(diag::warn_redundant_loop_iteration,2210 Third->getBeginLoc()))2211 return;2212 2213 bool LoopIncrement, LastIncrement;2214 DeclRefExpr *LoopDRE, *LastDRE;2215 2216 if (!ProcessIterationStmt(S, Third, LoopIncrement, LoopDRE)) return;2217 if (!ProcessIterationStmt(S, LastStmt, LastIncrement, LastDRE)) return;2218 2219 // Check that the two statements are both increments or both decrements2220 // on the same variable.2221 if (LoopIncrement != LastIncrement ||2222 LoopDRE->getDecl() != LastDRE->getDecl()) return;2223 2224 if (BreakContinueFinder(S, Body).ContinueFound()) return;2225 2226 S.Diag(LastDRE->getLocation(), diag::warn_redundant_loop_iteration)2227 << LastDRE->getDecl() << LastIncrement;2228 S.Diag(LoopDRE->getLocation(), diag::note_loop_iteration_here)2229 << LoopIncrement;2230 }2231 2232} // end namespace2233 2234 2235void Sema::CheckBreakContinueBinding(Expr *E) {2236 if (!E || getLangOpts().CPlusPlus)2237 return;2238 BreakContinueFinder BCFinder(*this, E);2239 Scope *BreakParent = CurScope->getBreakParent();2240 if (BCFinder.BreakFound() && BreakParent) {2241 if (BreakParent->getFlags() & Scope::SwitchScope) {2242 Diag(BCFinder.GetBreakLoc(), diag::warn_break_binds_to_switch);2243 } else {2244 Diag(BCFinder.GetBreakLoc(), diag::warn_loop_ctrl_binds_to_inner)2245 << "break";2246 }2247 } else if (BCFinder.ContinueFound() && CurScope->getContinueParent()) {2248 Diag(BCFinder.GetContinueLoc(), diag::warn_loop_ctrl_binds_to_inner)2249 << "continue";2250 }2251}2252 2253StmtResult Sema::ActOnForStmt(SourceLocation ForLoc, SourceLocation LParenLoc,2254 Stmt *First, ConditionResult Second,2255 FullExprArg third, SourceLocation RParenLoc,2256 Stmt *Body) {2257 if (Second.isInvalid())2258 return StmtError();2259 2260 if (!getLangOpts().CPlusPlus) {2261 if (DeclStmt *DS = dyn_cast_or_null<DeclStmt>(First)) {2262 // C99 6.8.5p3: The declaration part of a 'for' statement shall only2263 // declare identifiers for objects having storage class 'auto' or2264 // 'register'.2265 const Decl *NonVarSeen = nullptr;2266 bool VarDeclSeen = false;2267 for (auto *DI : DS->decls()) {2268 if (VarDecl *VD = dyn_cast<VarDecl>(DI)) {2269 VarDeclSeen = true;2270 if (VD->isLocalVarDecl() && !VD->hasLocalStorage())2271 Diag(DI->getLocation(),2272 getLangOpts().C232273 ? diag::warn_c17_non_local_variable_decl_in_for2274 : diag::ext_c23_non_local_variable_decl_in_for);2275 } else if (!NonVarSeen) {2276 // Keep track of the first non-variable declaration we saw so that2277 // we can diagnose if we don't see any variable declarations. This2278 // covers a case like declaring a typedef, function, or structure2279 // type rather than a variable.2280 //2281 // Note, _Static_assert is acceptable because it does not declare an2282 // identifier at all, so "for object having" does not apply.2283 if (!isa<StaticAssertDecl>(DI))2284 NonVarSeen = DI;2285 }2286 }2287 // Diagnose if we saw a non-variable declaration but no variable2288 // declarations.2289 if (NonVarSeen && !VarDeclSeen)2290 Diag(NonVarSeen->getLocation(),2291 getLangOpts().C23 ? diag::warn_c17_non_variable_decl_in_for2292 : diag::ext_c23_non_variable_decl_in_for);2293 }2294 }2295 2296 CheckBreakContinueBinding(Second.get().second);2297 CheckBreakContinueBinding(third.get());2298 2299 if (!Second.get().first)2300 CheckForLoopConditionalStatement(*this, Second.get().second, third.get(),2301 Body);2302 CheckForRedundantIteration(*this, third.get(), Body);2303 2304 if (Second.get().second &&2305 !Diags.isIgnored(diag::warn_comma_operator,2306 Second.get().second->getExprLoc()))2307 CommaVisitor(*this).Visit(Second.get().second);2308 2309 Expr *Third = third.release().getAs<Expr>();2310 if (isa<NullStmt>(Body))2311 getCurCompoundScope().setHasEmptyLoopBodies();2312 2313 return new (Context)2314 ForStmt(Context, First, Second.get().second, Second.get().first, Third,2315 Body, ForLoc, LParenLoc, RParenLoc);2316}2317 2318StmtResult Sema::ActOnForEachLValueExpr(Expr *E) {2319 // Reduce placeholder expressions here. Note that this rejects the2320 // use of pseudo-object l-values in this position.2321 ExprResult result = CheckPlaceholderExpr(E);2322 if (result.isInvalid()) return StmtError();2323 E = result.get();2324 2325 ExprResult FullExpr = ActOnFinishFullExpr(E, /*DiscardedValue*/ false);2326 if (FullExpr.isInvalid())2327 return StmtError();2328 return StmtResult(static_cast<Stmt*>(FullExpr.get()));2329}2330 2331/// Finish building a variable declaration for a for-range statement.2332/// \return true if an error occurs.2333static bool FinishForRangeVarDecl(Sema &SemaRef, VarDecl *Decl, Expr *Init,2334 SourceLocation Loc, int DiagID) {2335 if (Decl->getType()->isUndeducedType()) {2336 ExprResult Res = Init;2337 if (!Res.isUsable()) {2338 Decl->setInvalidDecl();2339 return true;2340 }2341 Init = Res.get();2342 }2343 2344 // Deduce the type for the iterator variable now rather than leaving it to2345 // AddInitializerToDecl, so we can produce a more suitable diagnostic.2346 QualType InitType;2347 if (!isa<InitListExpr>(Init) && Init->getType()->isVoidType()) {2348 SemaRef.Diag(Loc, DiagID) << Init->getType();2349 } else {2350 TemplateDeductionInfo Info(Init->getExprLoc());2351 TemplateDeductionResult Result = SemaRef.DeduceAutoType(2352 Decl->getTypeSourceInfo()->getTypeLoc(), Init, InitType, Info);2353 if (Result != TemplateDeductionResult::Success &&2354 Result != TemplateDeductionResult::AlreadyDiagnosed)2355 SemaRef.Diag(Loc, DiagID) << Init->getType();2356 }2357 2358 if (InitType.isNull()) {2359 Decl->setInvalidDecl();2360 return true;2361 }2362 Decl->setType(InitType);2363 2364 // In ARC, infer lifetime.2365 // FIXME: ARC may want to turn this into 'const __unsafe_unretained' if2366 // we're doing the equivalent of fast iteration.2367 if (SemaRef.getLangOpts().ObjCAutoRefCount &&2368 SemaRef.ObjC().inferObjCARCLifetime(Decl))2369 Decl->setInvalidDecl();2370 2371 SemaRef.AddInitializerToDecl(Decl, Init, /*DirectInit=*/false);2372 SemaRef.FinalizeDeclaration(Decl);2373 SemaRef.CurContext->addHiddenDecl(Decl);2374 return false;2375}2376 2377namespace {2378// An enum to represent whether something is dealing with a call to begin()2379// or a call to end() in a range-based for loop.2380enum BeginEndFunction {2381 BEF_begin,2382 BEF_end2383};2384 2385/// Produce a note indicating which begin/end function was implicitly called2386/// by a C++11 for-range statement. This is often not obvious from the code,2387/// nor from the diagnostics produced when analysing the implicit expressions2388/// required in a for-range statement.2389void NoteForRangeBeginEndFunction(Sema &SemaRef, Expr *E,2390 BeginEndFunction BEF) {2391 CallExpr *CE = dyn_cast<CallExpr>(E);2392 if (!CE)2393 return;2394 FunctionDecl *D = dyn_cast<FunctionDecl>(CE->getCalleeDecl());2395 if (!D)2396 return;2397 SourceLocation Loc = D->getLocation();2398 2399 std::string Description;2400 bool IsTemplate = false;2401 if (FunctionTemplateDecl *FunTmpl = D->getPrimaryTemplate()) {2402 Description = SemaRef.getTemplateArgumentBindingsText(2403 FunTmpl->getTemplateParameters(), *D->getTemplateSpecializationArgs());2404 IsTemplate = true;2405 }2406 2407 SemaRef.Diag(Loc, diag::note_for_range_begin_end)2408 << BEF << IsTemplate << Description << E->getType();2409}2410 2411/// Build a variable declaration for a for-range statement.2412VarDecl *BuildForRangeVarDecl(Sema &SemaRef, SourceLocation Loc,2413 QualType Type, StringRef Name) {2414 DeclContext *DC = SemaRef.CurContext;2415 IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name);2416 TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc);2417 VarDecl *Decl = VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type,2418 TInfo, SC_None);2419 Decl->setImplicit();2420 Decl->setCXXForRangeImplicitVar(true);2421 return Decl;2422}2423 2424}2425 2426static bool ObjCEnumerationCollection(Expr *Collection) {2427 return !Collection->isTypeDependent()2428 && Collection->getType()->getAs<ObjCObjectPointerType>() != nullptr;2429}2430 2431StmtResult Sema::ActOnCXXForRangeStmt(2432 Scope *S, SourceLocation ForLoc, SourceLocation CoawaitLoc, Stmt *InitStmt,2433 Stmt *First, SourceLocation ColonLoc, Expr *Range, SourceLocation RParenLoc,2434 BuildForRangeKind Kind,2435 ArrayRef<MaterializeTemporaryExpr *> LifetimeExtendTemps) {2436 // FIXME: recover in order to allow the body to be parsed.2437 if (!First)2438 return StmtError();2439 2440 if (Range && ObjCEnumerationCollection(Range)) {2441 // FIXME: Support init-statements in Objective-C++20 ranged for statement.2442 if (InitStmt)2443 return Diag(InitStmt->getBeginLoc(), diag::err_objc_for_range_init_stmt)2444 << InitStmt->getSourceRange();2445 return ObjC().ActOnObjCForCollectionStmt(ForLoc, First, Range, RParenLoc);2446 }2447 2448 DeclStmt *DS = dyn_cast<DeclStmt>(First);2449 assert(DS && "first part of for range not a decl stmt");2450 2451 if (!DS->isSingleDecl()) {2452 Diag(DS->getBeginLoc(), diag::err_type_defined_in_for_range);2453 return StmtError();2454 }2455 2456 // This function is responsible for attaching an initializer to LoopVar. We2457 // must call ActOnInitializerError if we fail to do so.2458 Decl *LoopVar = DS->getSingleDecl();2459 if (LoopVar->isInvalidDecl() || !Range ||2460 DiagnoseUnexpandedParameterPack(Range, UPPC_Expression)) {2461 ActOnInitializerError(LoopVar);2462 return StmtError();2463 }2464 2465 // Build the coroutine state immediately and not later during template2466 // instantiation2467 if (!CoawaitLoc.isInvalid()) {2468 if (!ActOnCoroutineBodyStart(S, CoawaitLoc, "co_await")) {2469 ActOnInitializerError(LoopVar);2470 return StmtError();2471 }2472 }2473 2474 // Build auto && __range = range-init2475 // Divide by 2, since the variables are in the inner scope (loop body).2476 const auto DepthStr = std::to_string(S->getDepth() / 2);2477 SourceLocation RangeLoc = Range->getBeginLoc();2478 VarDecl *RangeVar = BuildForRangeVarDecl(*this, RangeLoc,2479 Context.getAutoRRefDeductType(),2480 std::string("__range") + DepthStr);2481 if (FinishForRangeVarDecl(*this, RangeVar, Range, RangeLoc,2482 diag::err_for_range_deduction_failure)) {2483 ActOnInitializerError(LoopVar);2484 return StmtError();2485 }2486 2487 // Claim the type doesn't contain auto: we've already done the checking.2488 DeclGroupPtrTy RangeGroup =2489 BuildDeclaratorGroup(MutableArrayRef<Decl *>((Decl **)&RangeVar, 1));2490 StmtResult RangeDecl = ActOnDeclStmt(RangeGroup, RangeLoc, RangeLoc);2491 if (RangeDecl.isInvalid()) {2492 ActOnInitializerError(LoopVar);2493 return StmtError();2494 }2495 2496 StmtResult R = BuildCXXForRangeStmt(2497 ForLoc, CoawaitLoc, InitStmt, ColonLoc, RangeDecl.get(),2498 /*BeginStmt=*/nullptr, /*EndStmt=*/nullptr,2499 /*Cond=*/nullptr, /*Inc=*/nullptr, DS, RParenLoc, Kind,2500 LifetimeExtendTemps);2501 if (R.isInvalid()) {2502 ActOnInitializerError(LoopVar);2503 return StmtError();2504 }2505 2506 return R;2507}2508 2509/// Create the initialization, compare, and increment steps for2510/// the range-based for loop expression.2511/// This function does not handle array-based for loops,2512/// which are created in Sema::BuildCXXForRangeStmt.2513///2514/// \returns a ForRangeStatus indicating success or what kind of error occurred.2515/// BeginExpr and EndExpr are set and FRS_Success is returned on success;2516/// CandidateSet and BEF are set and some non-success value is returned on2517/// failure.2518static Sema::ForRangeStatus2519BuildNonArrayForRange(Sema &SemaRef, Expr *BeginRange, Expr *EndRange,2520 QualType RangeType, VarDecl *BeginVar, VarDecl *EndVar,2521 SourceLocation ColonLoc, SourceLocation CoawaitLoc,2522 OverloadCandidateSet *CandidateSet, ExprResult *BeginExpr,2523 ExprResult *EndExpr, BeginEndFunction *BEF) {2524 DeclarationNameInfo BeginNameInfo(2525 &SemaRef.PP.getIdentifierTable().get("begin"), ColonLoc);2526 DeclarationNameInfo EndNameInfo(&SemaRef.PP.getIdentifierTable().get("end"),2527 ColonLoc);2528 2529 LookupResult BeginMemberLookup(SemaRef, BeginNameInfo,2530 Sema::LookupMemberName);2531 LookupResult EndMemberLookup(SemaRef, EndNameInfo, Sema::LookupMemberName);2532 2533 auto BuildBegin = [&] {2534 *BEF = BEF_begin;2535 Sema::ForRangeStatus RangeStatus =2536 SemaRef.BuildForRangeBeginEndCall(ColonLoc, ColonLoc, BeginNameInfo,2537 BeginMemberLookup, CandidateSet,2538 BeginRange, BeginExpr);2539 2540 if (RangeStatus != Sema::FRS_Success) {2541 if (RangeStatus == Sema::FRS_DiagnosticIssued)2542 SemaRef.Diag(BeginRange->getBeginLoc(), diag::note_in_for_range)2543 << ColonLoc << BEF_begin << BeginRange->getType();2544 return RangeStatus;2545 }2546 if (!CoawaitLoc.isInvalid()) {2547 // FIXME: getCurScope() should not be used during template instantiation.2548 // We should pick up the set of unqualified lookup results for operator2549 // co_await during the initial parse.2550 *BeginExpr = SemaRef.ActOnCoawaitExpr(SemaRef.getCurScope(), ColonLoc,2551 BeginExpr->get());2552 if (BeginExpr->isInvalid())2553 return Sema::FRS_DiagnosticIssued;2554 }2555 if (FinishForRangeVarDecl(SemaRef, BeginVar, BeginExpr->get(), ColonLoc,2556 diag::err_for_range_iter_deduction_failure)) {2557 NoteForRangeBeginEndFunction(SemaRef, BeginExpr->get(), *BEF);2558 return Sema::FRS_DiagnosticIssued;2559 }2560 return Sema::FRS_Success;2561 };2562 2563 auto BuildEnd = [&] {2564 *BEF = BEF_end;2565 Sema::ForRangeStatus RangeStatus =2566 SemaRef.BuildForRangeBeginEndCall(ColonLoc, ColonLoc, EndNameInfo,2567 EndMemberLookup, CandidateSet,2568 EndRange, EndExpr);2569 if (RangeStatus != Sema::FRS_Success) {2570 if (RangeStatus == Sema::FRS_DiagnosticIssued)2571 SemaRef.Diag(EndRange->getBeginLoc(), diag::note_in_for_range)2572 << ColonLoc << BEF_end << EndRange->getType();2573 return RangeStatus;2574 }2575 if (FinishForRangeVarDecl(SemaRef, EndVar, EndExpr->get(), ColonLoc,2576 diag::err_for_range_iter_deduction_failure)) {2577 NoteForRangeBeginEndFunction(SemaRef, EndExpr->get(), *BEF);2578 return Sema::FRS_DiagnosticIssued;2579 }2580 return Sema::FRS_Success;2581 };2582 2583 if (CXXRecordDecl *D = RangeType->getAsCXXRecordDecl()) {2584 // - if _RangeT is a class type, the unqualified-ids begin and end are2585 // looked up in the scope of class _RangeT as if by class member access2586 // lookup (3.4.5), and if either (or both) finds at least one2587 // declaration, begin-expr and end-expr are __range.begin() and2588 // __range.end(), respectively;2589 SemaRef.LookupQualifiedName(BeginMemberLookup, D);2590 if (BeginMemberLookup.isAmbiguous())2591 return Sema::FRS_DiagnosticIssued;2592 2593 SemaRef.LookupQualifiedName(EndMemberLookup, D);2594 if (EndMemberLookup.isAmbiguous())2595 return Sema::FRS_DiagnosticIssued;2596 2597 if (BeginMemberLookup.empty() != EndMemberLookup.empty()) {2598 // Look up the non-member form of the member we didn't find, first.2599 // This way we prefer a "no viable 'end'" diagnostic over a "i found2600 // a 'begin' but ignored it because there was no member 'end'"2601 // diagnostic.2602 auto BuildNonmember = [&](2603 BeginEndFunction BEFFound, LookupResult &Found,2604 llvm::function_ref<Sema::ForRangeStatus()> BuildFound,2605 llvm::function_ref<Sema::ForRangeStatus()> BuildNotFound) {2606 LookupResult OldFound = std::move(Found);2607 Found.clear();2608 2609 if (Sema::ForRangeStatus Result = BuildNotFound())2610 return Result;2611 2612 switch (BuildFound()) {2613 case Sema::FRS_Success:2614 return Sema::FRS_Success;2615 2616 case Sema::FRS_NoViableFunction:2617 CandidateSet->NoteCandidates(2618 PartialDiagnosticAt(BeginRange->getBeginLoc(),2619 SemaRef.PDiag(diag::err_for_range_invalid)2620 << BeginRange->getType() << BEFFound),2621 SemaRef, OCD_AllCandidates, BeginRange);2622 [[fallthrough]];2623 2624 case Sema::FRS_DiagnosticIssued:2625 for (NamedDecl *D : OldFound) {2626 SemaRef.Diag(D->getLocation(),2627 diag::note_for_range_member_begin_end_ignored)2628 << BeginRange->getType() << BEFFound;2629 }2630 return Sema::FRS_DiagnosticIssued;2631 }2632 llvm_unreachable("unexpected ForRangeStatus");2633 };2634 if (BeginMemberLookup.empty())2635 return BuildNonmember(BEF_end, EndMemberLookup, BuildEnd, BuildBegin);2636 return BuildNonmember(BEF_begin, BeginMemberLookup, BuildBegin, BuildEnd);2637 }2638 } else {2639 // - otherwise, begin-expr and end-expr are begin(__range) and2640 // end(__range), respectively, where begin and end are looked up with2641 // argument-dependent lookup (3.4.2). For the purposes of this name2642 // lookup, namespace std is an associated namespace.2643 }2644 2645 if (Sema::ForRangeStatus Result = BuildBegin())2646 return Result;2647 return BuildEnd();2648}2649 2650/// Speculatively attempt to dereference an invalid range expression.2651/// If the attempt fails, this function will return a valid, null StmtResult2652/// and emit no diagnostics.2653static StmtResult RebuildForRangeWithDereference(Sema &SemaRef, Scope *S,2654 SourceLocation ForLoc,2655 SourceLocation CoawaitLoc,2656 Stmt *InitStmt,2657 Stmt *LoopVarDecl,2658 SourceLocation ColonLoc,2659 Expr *Range,2660 SourceLocation RangeLoc,2661 SourceLocation RParenLoc) {2662 // Determine whether we can rebuild the for-range statement with a2663 // dereferenced range expression.2664 ExprResult AdjustedRange;2665 {2666 Sema::SFINAETrap Trap(SemaRef);2667 2668 AdjustedRange = SemaRef.BuildUnaryOp(S, RangeLoc, UO_Deref, Range);2669 if (AdjustedRange.isInvalid())2670 return StmtResult();2671 2672 StmtResult SR = SemaRef.ActOnCXXForRangeStmt(2673 S, ForLoc, CoawaitLoc, InitStmt, LoopVarDecl, ColonLoc,2674 AdjustedRange.get(), RParenLoc, Sema::BFRK_Check);2675 if (SR.isInvalid())2676 return StmtResult();2677 }2678 2679 // The attempt to dereference worked well enough that it could produce a valid2680 // loop. Produce a fixit, and rebuild the loop with diagnostics enabled, in2681 // case there are any other (non-fatal) problems with it.2682 SemaRef.Diag(RangeLoc, diag::err_for_range_dereference)2683 << Range->getType() << FixItHint::CreateInsertion(RangeLoc, "*");2684 return SemaRef.ActOnCXXForRangeStmt(2685 S, ForLoc, CoawaitLoc, InitStmt, LoopVarDecl, ColonLoc,2686 AdjustedRange.get(), RParenLoc, Sema::BFRK_Rebuild);2687}2688 2689StmtResult Sema::BuildCXXForRangeStmt(2690 SourceLocation ForLoc, SourceLocation CoawaitLoc, Stmt *InitStmt,2691 SourceLocation ColonLoc, Stmt *RangeDecl, Stmt *Begin, Stmt *End,2692 Expr *Cond, Expr *Inc, Stmt *LoopVarDecl, SourceLocation RParenLoc,2693 BuildForRangeKind Kind,2694 ArrayRef<MaterializeTemporaryExpr *> LifetimeExtendTemps) {2695 // FIXME: This should not be used during template instantiation. We should2696 // pick up the set of unqualified lookup results for the != and + operators2697 // in the initial parse.2698 //2699 // Testcase (accepts-invalid):2700 // template<typename T> void f() { for (auto x : T()) {} }2701 // namespace N { struct X { X begin(); X end(); int operator*(); }; }2702 // bool operator!=(N::X, N::X); void operator++(N::X);2703 // void g() { f<N::X>(); }2704 Scope *S = getCurScope();2705 2706 DeclStmt *RangeDS = cast<DeclStmt>(RangeDecl);2707 VarDecl *RangeVar = cast<VarDecl>(RangeDS->getSingleDecl());2708 QualType RangeVarType = RangeVar->getType();2709 2710 DeclStmt *LoopVarDS = cast<DeclStmt>(LoopVarDecl);2711 VarDecl *LoopVar = cast<VarDecl>(LoopVarDS->getSingleDecl());2712 2713 StmtResult BeginDeclStmt = Begin;2714 StmtResult EndDeclStmt = End;2715 ExprResult NotEqExpr = Cond, IncrExpr = Inc;2716 2717 if (RangeVarType->isDependentType()) {2718 // The range is implicitly used as a placeholder when it is dependent.2719 RangeVar->markUsed(Context);2720 2721 // Deduce any 'auto's in the loop variable as 'DependentTy'. We'll fill2722 // them in properly when we instantiate the loop.2723 if (!LoopVar->isInvalidDecl() && Kind != BFRK_Check) {2724 if (auto *DD = dyn_cast<DecompositionDecl>(LoopVar))2725 for (auto *Binding : DD->bindings()) {2726 if (!Binding->isParameterPack())2727 Binding->setType(Context.DependentTy);2728 }2729 LoopVar->setType(SubstAutoTypeDependent(LoopVar->getType()));2730 }2731 } else if (!BeginDeclStmt.get()) {2732 SourceLocation RangeLoc = RangeVar->getLocation();2733 2734 const QualType RangeVarNonRefType = RangeVarType.getNonReferenceType();2735 2736 ExprResult BeginRangeRef = BuildDeclRefExpr(RangeVar, RangeVarNonRefType,2737 VK_LValue, ColonLoc);2738 if (BeginRangeRef.isInvalid())2739 return StmtError();2740 2741 ExprResult EndRangeRef = BuildDeclRefExpr(RangeVar, RangeVarNonRefType,2742 VK_LValue, ColonLoc);2743 if (EndRangeRef.isInvalid())2744 return StmtError();2745 2746 QualType AutoType = Context.getAutoDeductType();2747 Expr *Range = RangeVar->getInit();2748 if (!Range)2749 return StmtError();2750 QualType RangeType = Range->getType();2751 2752 if (RequireCompleteType(RangeLoc, RangeType,2753 diag::err_for_range_incomplete_type))2754 return StmtError();2755 2756 // P2718R0 - Lifetime extension in range-based for loops.2757 if (getLangOpts().CPlusPlus23 && !LifetimeExtendTemps.empty()) {2758 InitializedEntity Entity =2759 InitializedEntity::InitializeVariable(RangeVar);2760 for (auto *MTE : LifetimeExtendTemps)2761 MTE->setExtendingDecl(RangeVar, Entity.allocateManglingNumber());2762 }2763 2764 // Build auto __begin = begin-expr, __end = end-expr.2765 // Divide by 2, since the variables are in the inner scope (loop body).2766 const auto DepthStr = std::to_string(S->getDepth() / 2);2767 VarDecl *BeginVar = BuildForRangeVarDecl(*this, ColonLoc, AutoType,2768 std::string("__begin") + DepthStr);2769 VarDecl *EndVar = BuildForRangeVarDecl(*this, ColonLoc, AutoType,2770 std::string("__end") + DepthStr);2771 2772 // Build begin-expr and end-expr and attach to __begin and __end variables.2773 ExprResult BeginExpr, EndExpr;2774 if (const ArrayType *UnqAT = RangeType->getAsArrayTypeUnsafe()) {2775 // - if _RangeT is an array type, begin-expr and end-expr are __range and2776 // __range + __bound, respectively, where __bound is the array bound. If2777 // _RangeT is an array of unknown size or an array of incomplete type,2778 // the program is ill-formed;2779 2780 // begin-expr is __range.2781 BeginExpr = BeginRangeRef;2782 if (!CoawaitLoc.isInvalid()) {2783 BeginExpr = ActOnCoawaitExpr(S, ColonLoc, BeginExpr.get());2784 if (BeginExpr.isInvalid())2785 return StmtError();2786 }2787 if (FinishForRangeVarDecl(*this, BeginVar, BeginRangeRef.get(), ColonLoc,2788 diag::err_for_range_iter_deduction_failure)) {2789 NoteForRangeBeginEndFunction(*this, BeginExpr.get(), BEF_begin);2790 return StmtError();2791 }2792 2793 // Find the array bound.2794 ExprResult BoundExpr;2795 if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(UnqAT))2796 BoundExpr = IntegerLiteral::Create(2797 Context, CAT->getSize(), Context.getPointerDiffType(), RangeLoc);2798 else if (const VariableArrayType *VAT =2799 dyn_cast<VariableArrayType>(UnqAT)) {2800 // For a variably modified type we can't just use the expression within2801 // the array bounds, since we don't want that to be re-evaluated here.2802 // Rather, we need to determine what it was when the array was first2803 // created - so we resort to using sizeof(vla)/sizeof(element).2804 // For e.g.2805 // void f(int b) {2806 // int vla[b];2807 // b = -1; <-- This should not affect the num of iterations below2808 // for (int &c : vla) { .. }2809 // }2810 2811 // FIXME: This results in codegen generating IR that recalculates the2812 // run-time number of elements (as opposed to just using the IR Value2813 // that corresponds to the run-time value of each bound that was2814 // generated when the array was created.) If this proves too embarrassing2815 // even for unoptimized IR, consider passing a magic-value/cookie to2816 // codegen that then knows to simply use that initial llvm::Value (that2817 // corresponds to the bound at time of array creation) within2818 // getelementptr. But be prepared to pay the price of increasing a2819 // customized form of coupling between the two components - which could2820 // be hard to maintain as the codebase evolves.2821 2822 ExprResult SizeOfVLAExprR = ActOnUnaryExprOrTypeTraitExpr(2823 EndVar->getLocation(), UETT_SizeOf,2824 /*IsType=*/true,2825 CreateParsedType(VAT->desugar(), Context.getTrivialTypeSourceInfo(2826 VAT->desugar(), RangeLoc))2827 .getAsOpaquePtr(),2828 EndVar->getSourceRange());2829 if (SizeOfVLAExprR.isInvalid())2830 return StmtError();2831 2832 ExprResult SizeOfEachElementExprR = ActOnUnaryExprOrTypeTraitExpr(2833 EndVar->getLocation(), UETT_SizeOf,2834 /*IsType=*/true,2835 CreateParsedType(VAT->desugar(),2836 Context.getTrivialTypeSourceInfo(2837 VAT->getElementType(), RangeLoc))2838 .getAsOpaquePtr(),2839 EndVar->getSourceRange());2840 if (SizeOfEachElementExprR.isInvalid())2841 return StmtError();2842 2843 BoundExpr =2844 ActOnBinOp(S, EndVar->getLocation(), tok::slash,2845 SizeOfVLAExprR.get(), SizeOfEachElementExprR.get());2846 if (BoundExpr.isInvalid())2847 return StmtError();2848 2849 } else {2850 // Can't be a DependentSizedArrayType or an IncompleteArrayType since2851 // UnqAT is not incomplete and Range is not type-dependent.2852 llvm_unreachable("Unexpected array type in for-range");2853 }2854 2855 // end-expr is __range + __bound.2856 EndExpr = ActOnBinOp(S, ColonLoc, tok::plus, EndRangeRef.get(),2857 BoundExpr.get());2858 if (EndExpr.isInvalid())2859 return StmtError();2860 if (FinishForRangeVarDecl(*this, EndVar, EndExpr.get(), ColonLoc,2861 diag::err_for_range_iter_deduction_failure)) {2862 NoteForRangeBeginEndFunction(*this, EndExpr.get(), BEF_end);2863 return StmtError();2864 }2865 } else {2866 OverloadCandidateSet CandidateSet(RangeLoc,2867 OverloadCandidateSet::CSK_Normal);2868 BeginEndFunction BEFFailure;2869 ForRangeStatus RangeStatus = BuildNonArrayForRange(2870 *this, BeginRangeRef.get(), EndRangeRef.get(), RangeType, BeginVar,2871 EndVar, ColonLoc, CoawaitLoc, &CandidateSet, &BeginExpr, &EndExpr,2872 &BEFFailure);2873 2874 if (Kind == BFRK_Build && RangeStatus == FRS_NoViableFunction &&2875 BEFFailure == BEF_begin) {2876 // If the range is being built from an array parameter, emit a2877 // a diagnostic that it is being treated as a pointer.2878 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Range)) {2879 if (ParmVarDecl *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {2880 QualType ArrayTy = PVD->getOriginalType();2881 QualType PointerTy = PVD->getType();2882 if (PointerTy->isPointerType() && ArrayTy->isArrayType()) {2883 Diag(Range->getBeginLoc(), diag::err_range_on_array_parameter)2884 << RangeLoc << PVD << ArrayTy << PointerTy;2885 Diag(PVD->getLocation(), diag::note_declared_at);2886 return StmtError();2887 }2888 }2889 }2890 2891 // If building the range failed, try dereferencing the range expression2892 // unless a diagnostic was issued or the end function is problematic.2893 StmtResult SR = RebuildForRangeWithDereference(*this, S, ForLoc,2894 CoawaitLoc, InitStmt,2895 LoopVarDecl, ColonLoc,2896 Range, RangeLoc,2897 RParenLoc);2898 if (SR.isInvalid() || SR.isUsable())2899 return SR;2900 }2901 2902 // Otherwise, emit diagnostics if we haven't already.2903 if (RangeStatus == FRS_NoViableFunction) {2904 Expr *Range = BEFFailure ? EndRangeRef.get() : BeginRangeRef.get();2905 CandidateSet.NoteCandidates(2906 PartialDiagnosticAt(Range->getBeginLoc(),2907 PDiag(diag::err_for_range_invalid)2908 << RangeLoc << Range->getType()2909 << BEFFailure),2910 *this, OCD_AllCandidates, Range);2911 }2912 // Return an error if no fix was discovered.2913 if (RangeStatus != FRS_Success)2914 return StmtError();2915 }2916 2917 assert(!BeginExpr.isInvalid() && !EndExpr.isInvalid() &&2918 "invalid range expression in for loop");2919 2920 // C++11 [dcl.spec.auto]p7: BeginType and EndType must be the same.2921 // C++1z removes this restriction.2922 QualType BeginType = BeginVar->getType(), EndType = EndVar->getType();2923 if (!Context.hasSameType(BeginType, EndType)) {2924 Diag(RangeLoc, getLangOpts().CPlusPlus172925 ? diag::warn_for_range_begin_end_types_differ2926 : diag::ext_for_range_begin_end_types_differ)2927 << BeginType << EndType;2928 NoteForRangeBeginEndFunction(*this, BeginExpr.get(), BEF_begin);2929 NoteForRangeBeginEndFunction(*this, EndExpr.get(), BEF_end);2930 }2931 2932 BeginDeclStmt =2933 ActOnDeclStmt(ConvertDeclToDeclGroup(BeginVar), ColonLoc, ColonLoc);2934 EndDeclStmt =2935 ActOnDeclStmt(ConvertDeclToDeclGroup(EndVar), ColonLoc, ColonLoc);2936 2937 const QualType BeginRefNonRefType = BeginType.getNonReferenceType();2938 ExprResult BeginRef = BuildDeclRefExpr(BeginVar, BeginRefNonRefType,2939 VK_LValue, ColonLoc);2940 if (BeginRef.isInvalid())2941 return StmtError();2942 2943 ExprResult EndRef = BuildDeclRefExpr(EndVar, EndType.getNonReferenceType(),2944 VK_LValue, ColonLoc);2945 if (EndRef.isInvalid())2946 return StmtError();2947 2948 // Build and check __begin != __end expression.2949 NotEqExpr = ActOnBinOp(S, ColonLoc, tok::exclaimequal,2950 BeginRef.get(), EndRef.get());2951 if (!NotEqExpr.isInvalid())2952 NotEqExpr = CheckBooleanCondition(ColonLoc, NotEqExpr.get());2953 if (!NotEqExpr.isInvalid())2954 NotEqExpr =2955 ActOnFinishFullExpr(NotEqExpr.get(), /*DiscardedValue*/ false);2956 if (NotEqExpr.isInvalid()) {2957 Diag(RangeLoc, diag::note_for_range_invalid_iterator)2958 << RangeLoc << 0 << BeginRangeRef.get()->getType();2959 NoteForRangeBeginEndFunction(*this, BeginExpr.get(), BEF_begin);2960 if (!Context.hasSameType(BeginType, EndType))2961 NoteForRangeBeginEndFunction(*this, EndExpr.get(), BEF_end);2962 return StmtError();2963 }2964 2965 // Build and check ++__begin expression.2966 BeginRef = BuildDeclRefExpr(BeginVar, BeginRefNonRefType,2967 VK_LValue, ColonLoc);2968 if (BeginRef.isInvalid())2969 return StmtError();2970 2971 IncrExpr = ActOnUnaryOp(S, ColonLoc, tok::plusplus, BeginRef.get());2972 if (!IncrExpr.isInvalid() && CoawaitLoc.isValid())2973 // FIXME: getCurScope() should not be used during template instantiation.2974 // We should pick up the set of unqualified lookup results for operator2975 // co_await during the initial parse.2976 IncrExpr = ActOnCoawaitExpr(S, CoawaitLoc, IncrExpr.get());2977 if (!IncrExpr.isInvalid())2978 IncrExpr = ActOnFinishFullExpr(IncrExpr.get(), /*DiscardedValue*/ false);2979 if (IncrExpr.isInvalid()) {2980 Diag(RangeLoc, diag::note_for_range_invalid_iterator)2981 << RangeLoc << 2 << BeginRangeRef.get()->getType() ;2982 NoteForRangeBeginEndFunction(*this, BeginExpr.get(), BEF_begin);2983 return StmtError();2984 }2985 2986 // Build and check *__begin expression.2987 BeginRef = BuildDeclRefExpr(BeginVar, BeginRefNonRefType,2988 VK_LValue, ColonLoc);2989 if (BeginRef.isInvalid())2990 return StmtError();2991 2992 ExprResult DerefExpr = ActOnUnaryOp(S, ColonLoc, tok::star, BeginRef.get());2993 if (DerefExpr.isInvalid()) {2994 Diag(RangeLoc, diag::note_for_range_invalid_iterator)2995 << RangeLoc << 1 << BeginRangeRef.get()->getType();2996 NoteForRangeBeginEndFunction(*this, BeginExpr.get(), BEF_begin);2997 return StmtError();2998 }2999 3000 // Attach *__begin as initializer for VD. Don't touch it if we're just3001 // trying to determine whether this would be a valid range.3002 if (!LoopVar->isInvalidDecl() && Kind != BFRK_Check) {3003 AddInitializerToDecl(LoopVar, DerefExpr.get(), /*DirectInit=*/false);3004 if (LoopVar->isInvalidDecl() ||3005 (LoopVar->getInit() && LoopVar->getInit()->containsErrors()))3006 NoteForRangeBeginEndFunction(*this, BeginExpr.get(), BEF_begin);3007 }3008 }3009 3010 // Don't bother to actually allocate the result if we're just trying to3011 // determine whether it would be valid.3012 if (Kind == BFRK_Check)3013 return StmtResult();3014 3015 // In OpenMP loop region loop control variable must be private. Perform3016 // analysis of first part (if any).3017 if (getLangOpts().OpenMP >= 50 && BeginDeclStmt.isUsable())3018 OpenMP().ActOnOpenMPLoopInitialization(ForLoc, BeginDeclStmt.get());3019 3020 return new (Context) CXXForRangeStmt(3021 InitStmt, RangeDS, cast_or_null<DeclStmt>(BeginDeclStmt.get()),3022 cast_or_null<DeclStmt>(EndDeclStmt.get()), NotEqExpr.get(),3023 IncrExpr.get(), LoopVarDS, /*Body=*/nullptr, ForLoc, CoawaitLoc,3024 ColonLoc, RParenLoc);3025}3026 3027// Warn when the loop variable is a const reference that creates a copy.3028// Suggest using the non-reference type for copies. If a copy can be prevented3029// suggest the const reference type that would do so.3030// For instance, given "for (const &Foo : Range)", suggest3031// "for (const Foo : Range)" to denote a copy is made for the loop. If3032// possible, also suggest "for (const &Bar : Range)" if this type prevents3033// the copy altogether.3034static void DiagnoseForRangeReferenceVariableCopies(Sema &SemaRef,3035 const VarDecl *VD,3036 QualType RangeInitType) {3037 const Expr *InitExpr = VD->getInit();3038 if (!InitExpr)3039 return;3040 3041 QualType VariableType = VD->getType();3042 3043 if (auto Cleanups = dyn_cast<ExprWithCleanups>(InitExpr))3044 if (!Cleanups->cleanupsHaveSideEffects())3045 InitExpr = Cleanups->getSubExpr();3046 3047 const MaterializeTemporaryExpr *MTE =3048 dyn_cast<MaterializeTemporaryExpr>(InitExpr);3049 3050 // No copy made.3051 if (!MTE)3052 return;3053 3054 const Expr *E = MTE->getSubExpr()->IgnoreImpCasts();3055 3056 // Searching for either UnaryOperator for dereference of a pointer or3057 // CXXOperatorCallExpr for handling iterators.3058 while (!isa<CXXOperatorCallExpr>(E) && !isa<UnaryOperator>(E)) {3059 if (const CXXConstructExpr *CCE = dyn_cast<CXXConstructExpr>(E)) {3060 E = CCE->getArg(0);3061 } else if (const CXXMemberCallExpr *Call = dyn_cast<CXXMemberCallExpr>(E)) {3062 const MemberExpr *ME = cast<MemberExpr>(Call->getCallee());3063 E = ME->getBase();3064 } else {3065 const MaterializeTemporaryExpr *MTE = cast<MaterializeTemporaryExpr>(E);3066 E = MTE->getSubExpr();3067 }3068 E = E->IgnoreImpCasts();3069 }3070 3071 QualType ReferenceReturnType;3072 if (isa<UnaryOperator>(E)) {3073 ReferenceReturnType = SemaRef.Context.getLValueReferenceType(E->getType());3074 } else {3075 const CXXOperatorCallExpr *Call = cast<CXXOperatorCallExpr>(E);3076 const FunctionDecl *FD = Call->getDirectCallee();3077 QualType ReturnType = FD->getReturnType();3078 if (ReturnType->isReferenceType())3079 ReferenceReturnType = ReturnType;3080 }3081 3082 if (!ReferenceReturnType.isNull()) {3083 // Loop variable creates a temporary. Suggest either to go with3084 // non-reference loop variable to indicate a copy is made, or3085 // the correct type to bind a const reference.3086 SemaRef.Diag(VD->getLocation(),3087 diag::warn_for_range_const_ref_binds_temp_built_from_ref)3088 << VD << VariableType << ReferenceReturnType;3089 QualType NonReferenceType = VariableType.getNonReferenceType();3090 NonReferenceType.removeLocalConst();3091 QualType NewReferenceType =3092 SemaRef.Context.getLValueReferenceType(E->getType().withConst());3093 SemaRef.Diag(VD->getBeginLoc(), diag::note_use_type_or_non_reference)3094 << NonReferenceType << NewReferenceType << VD->getSourceRange()3095 << FixItHint::CreateRemoval(VD->getTypeSpecEndLoc());3096 } else if (!VariableType->isRValueReferenceType()) {3097 // The range always returns a copy, so a temporary is always created.3098 // Suggest removing the reference from the loop variable.3099 // If the type is a rvalue reference do not warn since that changes the3100 // semantic of the code.3101 SemaRef.Diag(VD->getLocation(), diag::warn_for_range_ref_binds_ret_temp)3102 << VD << RangeInitType;3103 QualType NonReferenceType = VariableType.getNonReferenceType();3104 NonReferenceType.removeLocalConst();3105 SemaRef.Diag(VD->getBeginLoc(), diag::note_use_non_reference_type)3106 << NonReferenceType << VD->getSourceRange()3107 << FixItHint::CreateRemoval(VD->getTypeSpecEndLoc());3108 }3109}3110 3111/// Determines whether the @p VariableType's declaration is a record with the3112/// clang::trivial_abi attribute.3113static bool hasTrivialABIAttr(QualType VariableType) {3114 if (CXXRecordDecl *RD = VariableType->getAsCXXRecordDecl())3115 return RD->hasAttr<TrivialABIAttr>();3116 3117 return false;3118}3119 3120// Warns when the loop variable can be changed to a reference type to3121// prevent a copy. For instance, if given "for (const Foo x : Range)" suggest3122// "for (const Foo &x : Range)" if this form does not make a copy.3123static void DiagnoseForRangeConstVariableCopies(Sema &SemaRef,3124 const VarDecl *VD) {3125 const Expr *InitExpr = VD->getInit();3126 if (!InitExpr)3127 return;3128 3129 QualType VariableType = VD->getType();3130 3131 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(InitExpr)) {3132 if (!CE->getConstructor()->isCopyConstructor())3133 return;3134 } else if (const CastExpr *CE = dyn_cast<CastExpr>(InitExpr)) {3135 if (CE->getCastKind() != CK_LValueToRValue)3136 return;3137 } else {3138 return;3139 }3140 3141 // Small trivially copyable types are cheap to copy. Do not emit the3142 // diagnostic for these instances. 64 bytes is a common size of a cache line.3143 // (The function `getTypeSize` returns the size in bits.)3144 ASTContext &Ctx = SemaRef.Context;3145 if (Ctx.getTypeSize(VariableType) <= 64 * 8 &&3146 (VariableType.isTriviallyCopyConstructibleType(Ctx) ||3147 hasTrivialABIAttr(VariableType)))3148 return;3149 3150 // Suggest changing from a const variable to a const reference variable3151 // if doing so will prevent a copy.3152 SemaRef.Diag(VD->getLocation(), diag::warn_for_range_copy)3153 << VD << VariableType;3154 SemaRef.Diag(VD->getBeginLoc(), diag::note_use_reference_type)3155 << SemaRef.Context.getLValueReferenceType(VariableType)3156 << VD->getSourceRange()3157 << FixItHint::CreateInsertion(VD->getLocation(), "&");3158}3159 3160/// DiagnoseForRangeVariableCopies - Diagnose three cases and fixes for them.3161/// 1) for (const foo &x : foos) where foos only returns a copy. Suggest3162/// using "const foo x" to show that a copy is made3163/// 2) for (const bar &x : foos) where bar is a temporary initialized by bar.3164/// Suggest either "const bar x" to keep the copying or "const foo& x" to3165/// prevent the copy.3166/// 3) for (const foo x : foos) where x is constructed from a reference foo.3167/// Suggest "const foo &x" to prevent the copy.3168static void DiagnoseForRangeVariableCopies(Sema &SemaRef,3169 const CXXForRangeStmt *ForStmt) {3170 if (SemaRef.inTemplateInstantiation())3171 return;3172 3173 SourceLocation Loc = ForStmt->getBeginLoc();3174 if (SemaRef.Diags.isIgnored(3175 diag::warn_for_range_const_ref_binds_temp_built_from_ref, Loc) &&3176 SemaRef.Diags.isIgnored(diag::warn_for_range_ref_binds_ret_temp, Loc) &&3177 SemaRef.Diags.isIgnored(diag::warn_for_range_copy, Loc)) {3178 return;3179 }3180 3181 const VarDecl *VD = ForStmt->getLoopVariable();3182 if (!VD)3183 return;3184 3185 QualType VariableType = VD->getType();3186 3187 if (VariableType->isIncompleteType())3188 return;3189 3190 const Expr *InitExpr = VD->getInit();3191 if (!InitExpr)3192 return;3193 3194 if (InitExpr->getExprLoc().isMacroID())3195 return;3196 3197 if (VariableType->isReferenceType()) {3198 DiagnoseForRangeReferenceVariableCopies(SemaRef, VD,3199 ForStmt->getRangeInit()->getType());3200 } else if (VariableType.isConstQualified()) {3201 DiagnoseForRangeConstVariableCopies(SemaRef, VD);3202 }3203}3204 3205StmtResult Sema::FinishCXXForRangeStmt(Stmt *S, Stmt *B) {3206 if (!S || !B)3207 return StmtError();3208 3209 if (isa<ObjCForCollectionStmt>(S))3210 return ObjC().FinishObjCForCollectionStmt(S, B);3211 3212 CXXForRangeStmt *ForStmt = cast<CXXForRangeStmt>(S);3213 ForStmt->setBody(B);3214 3215 DiagnoseEmptyStmtBody(ForStmt->getRParenLoc(), B,3216 diag::warn_empty_range_based_for_body);3217 3218 DiagnoseForRangeVariableCopies(*this, ForStmt);3219 3220 return S;3221}3222 3223StmtResult Sema::ActOnGotoStmt(SourceLocation GotoLoc,3224 SourceLocation LabelLoc,3225 LabelDecl *TheDecl) {3226 setFunctionHasBranchIntoScope();3227 3228 // If this goto is in a compute construct scope, we need to make sure we check3229 // gotos in/out.3230 if (getCurScope()->isInOpenACCComputeConstructScope())3231 setFunctionHasBranchProtectedScope();3232 3233 TheDecl->markUsed(Context);3234 return new (Context) GotoStmt(TheDecl, GotoLoc, LabelLoc);3235}3236 3237StmtResult3238Sema::ActOnIndirectGotoStmt(SourceLocation GotoLoc, SourceLocation StarLoc,3239 Expr *E) {3240 // Convert operand to void*3241 if (!E->isTypeDependent()) {3242 QualType ETy = E->getType();3243 QualType DestTy = Context.getPointerType(Context.VoidTy.withConst());3244 ExprResult ExprRes = E;3245 AssignConvertType ConvTy =3246 CheckSingleAssignmentConstraints(DestTy, ExprRes);3247 if (ExprRes.isInvalid())3248 return StmtError();3249 E = ExprRes.get();3250 if (DiagnoseAssignmentResult(ConvTy, StarLoc, DestTy, ETy, E,3251 AssignmentAction::Passing))3252 return StmtError();3253 }3254 3255 ExprResult ExprRes = ActOnFinishFullExpr(E, /*DiscardedValue*/ false);3256 if (ExprRes.isInvalid())3257 return StmtError();3258 E = ExprRes.get();3259 3260 setFunctionHasIndirectGoto();3261 3262 // If this goto is in a compute construct scope, we need to make sure we3263 // check gotos in/out.3264 if (getCurScope()->isInOpenACCComputeConstructScope())3265 setFunctionHasBranchProtectedScope();3266 3267 return new (Context) IndirectGotoStmt(GotoLoc, StarLoc, E);3268}3269 3270static void CheckJumpOutOfSEHFinally(Sema &S, SourceLocation Loc,3271 const Scope &DestScope) {3272 if (!S.CurrentSEHFinally.empty() &&3273 DestScope.Contains(*S.CurrentSEHFinally.back())) {3274 S.Diag(Loc, diag::warn_jump_out_of_seh_finally);3275 }3276}3277 3278static Scope *FindLabeledBreakContinueScope(Sema &S, Scope *CurScope,3279 SourceLocation KWLoc,3280 LabelDecl *Target,3281 SourceLocation LabelLoc,3282 bool IsContinue) {3283 assert(Target && "not a named break/continue?");3284 3285 Target->markUsed(S.Context);3286 3287 Scope *Found = nullptr;3288 for (Scope *Scope = CurScope; Scope; Scope = Scope->getParent()) {3289 if (Scope->isFunctionScope())3290 break;3291 3292 if (Scope->isOpenACCComputeConstructScope()) {3293 S.Diag(KWLoc, diag::err_acc_branch_in_out_compute_construct)3294 << /*branch*/ 0 << /*out of*/ 0;3295 return nullptr;3296 }3297 3298 if (Scope->isBreakOrContinueScope() &&3299 Scope->getPrecedingLabel() == Target) {3300 Found = Scope;3301 break;3302 }3303 }3304 3305 if (Found) {3306 if (IsContinue && !Found->isContinueScope()) {3307 S.Diag(LabelLoc, diag::err_continue_switch);3308 return nullptr;3309 }3310 return Found;3311 }3312 3313 S.Diag(LabelLoc, diag::err_break_continue_label_not_found) << IsContinue;3314 return nullptr;3315}3316 3317StmtResult Sema::ActOnContinueStmt(SourceLocation ContinueLoc, Scope *CurScope,3318 LabelDecl *Target, SourceLocation LabelLoc) {3319 Scope *S;3320 if (Target) {3321 S = FindLabeledBreakContinueScope(*this, CurScope, ContinueLoc, Target,3322 LabelLoc,3323 /*IsContinue=*/true);3324 if (!S)3325 return StmtError();3326 } else {3327 S = CurScope->getContinueParent();3328 }3329 3330 if (!S) {3331 // C99 6.8.6.2p1: A break shall appear only in or as a loop body.3332 return StmtError(Diag(ContinueLoc, diag::err_continue_not_in_loop));3333 }3334 if (S->isConditionVarScope()) {3335 // We cannot 'continue;' from within a statement expression in the3336 // initializer of a condition variable because we would jump past the3337 // initialization of that variable.3338 return StmtError(Diag(ContinueLoc, diag::err_continue_from_cond_var_init));3339 }3340 3341 // A 'continue' that would normally have execution continue on a block outside3342 // of a compute construct counts as 'branching out of' the compute construct,3343 // so diagnose here.3344 if (S->isOpenACCComputeConstructScope())3345 return StmtError(3346 Diag(ContinueLoc, diag::err_acc_branch_in_out_compute_construct)3347 << /*branch*/ 0 << /*out of */ 0);3348 3349 CheckJumpOutOfSEHFinally(*this, ContinueLoc, *S);3350 3351 return new (Context) ContinueStmt(ContinueLoc, LabelLoc, Target);3352}3353 3354StmtResult Sema::ActOnBreakStmt(SourceLocation BreakLoc, Scope *CurScope,3355 LabelDecl *Target, SourceLocation LabelLoc) {3356 Scope *S;3357 if (Target) {3358 S = FindLabeledBreakContinueScope(*this, CurScope, BreakLoc, Target,3359 LabelLoc,3360 /*IsContinue=*/false);3361 if (!S)3362 return StmtError();3363 } else {3364 S = CurScope->getBreakParent();3365 }3366 3367 if (!S) {3368 // C99 6.8.6.3p1: A break shall appear only in or as a switch/loop body.3369 return StmtError(Diag(BreakLoc, diag::err_break_not_in_loop_or_switch));3370 }3371 3372 if (S->isOpenMPLoopScope())3373 return StmtError(Diag(BreakLoc, diag::err_omp_loop_cannot_use_stmt)3374 << "break");3375 3376 // OpenACC doesn't allow 'break'ing from a compute construct, so diagnose if3377 // we are trying to do so. This can come in 2 flavors: 1-the break'able thing3378 // (besides the compute construct) 'contains' the compute construct, at which3379 // point the 'break' scope will be the compute construct. Else it could be a3380 // loop of some sort that has a direct parent of the compute construct.3381 // However, a 'break' in a 'switch' marked as a compute construct doesn't3382 // count as 'branch out of' the compute construct.3383 if (S->isOpenACCComputeConstructScope() ||3384 (S->isLoopScope() && S->getParent() &&3385 S->getParent()->isOpenACCComputeConstructScope()))3386 return StmtError(3387 Diag(BreakLoc, diag::err_acc_branch_in_out_compute_construct)3388 << /*branch*/ 0 << /*out of */ 0);3389 3390 CheckJumpOutOfSEHFinally(*this, BreakLoc, *S);3391 3392 return new (Context) BreakStmt(BreakLoc, LabelLoc, Target);3393}3394 3395Sema::NamedReturnInfo Sema::getNamedReturnInfo(Expr *&E,3396 SimplerImplicitMoveMode Mode) {3397 if (!E)3398 return NamedReturnInfo();3399 // - in a return statement in a function [where] ...3400 // ... the expression is the name of a non-volatile automatic object ...3401 const auto *DR = dyn_cast<DeclRefExpr>(E->IgnoreParens());3402 if (!DR || DR->refersToEnclosingVariableOrCapture())3403 return NamedReturnInfo();3404 const auto *VD = dyn_cast<VarDecl>(DR->getDecl());3405 if (!VD)3406 return NamedReturnInfo();3407 if (VD->getInit() && VD->getInit()->containsErrors())3408 return NamedReturnInfo();3409 NamedReturnInfo Res = getNamedReturnInfo(VD);3410 if (Res.Candidate && !E->isXValue() &&3411 (Mode == SimplerImplicitMoveMode::ForceOn ||3412 (Mode != SimplerImplicitMoveMode::ForceOff &&3413 getLangOpts().CPlusPlus23))) {3414 E = ImplicitCastExpr::Create(Context, VD->getType().getNonReferenceType(),3415 CK_NoOp, E, nullptr, VK_XValue,3416 FPOptionsOverride());3417 }3418 return Res;3419}3420 3421Sema::NamedReturnInfo Sema::getNamedReturnInfo(const VarDecl *VD) {3422 NamedReturnInfo Info{VD, NamedReturnInfo::MoveEligibleAndCopyElidable};3423 3424 // C++20 [class.copy.elision]p3:3425 // - in a return statement in a function with ...3426 // (other than a function ... parameter)3427 if (VD->getKind() == Decl::ParmVar)3428 Info.S = NamedReturnInfo::MoveEligible;3429 else if (VD->getKind() != Decl::Var)3430 return NamedReturnInfo();3431 3432 // (other than ... a catch-clause parameter)3433 if (VD->isExceptionVariable())3434 Info.S = NamedReturnInfo::MoveEligible;3435 3436 // ...automatic...3437 if (!VD->hasLocalStorage())3438 return NamedReturnInfo();3439 3440 // We don't want to implicitly move out of a __block variable during a return3441 // because we cannot assume the variable will no longer be used.3442 if (VD->hasAttr<BlocksAttr>())3443 return NamedReturnInfo();3444 3445 QualType VDType = VD->getType();3446 if (VDType->isObjectType()) {3447 // C++17 [class.copy.elision]p3:3448 // ...non-volatile automatic object...3449 if (VDType.isVolatileQualified())3450 return NamedReturnInfo();3451 } else if (VDType->isRValueReferenceType()) {3452 // C++20 [class.copy.elision]p3:3453 // ...either a non-volatile object or an rvalue reference to a non-volatile3454 // object type...3455 QualType VDReferencedType = VDType.getNonReferenceType();3456 if (VDReferencedType.isVolatileQualified() ||3457 !VDReferencedType->isObjectType())3458 return NamedReturnInfo();3459 Info.S = NamedReturnInfo::MoveEligible;3460 } else {3461 return NamedReturnInfo();3462 }3463 3464 // Variables with higher required alignment than their type's ABI3465 // alignment cannot use NRVO.3466 if (!VD->hasDependentAlignment() && !VDType->isIncompleteType() &&3467 Context.getDeclAlign(VD) > Context.getTypeAlignInChars(VDType))3468 Info.S = NamedReturnInfo::MoveEligible;3469 3470 return Info;3471}3472 3473const VarDecl *Sema::getCopyElisionCandidate(NamedReturnInfo &Info,3474 QualType ReturnType) {3475 if (!Info.Candidate)3476 return nullptr;3477 3478 auto invalidNRVO = [&] {3479 Info = NamedReturnInfo();3480 return nullptr;3481 };3482 3483 // If we got a non-deduced auto ReturnType, we are in a dependent context and3484 // there is no point in allowing copy elision since we won't have it deduced3485 // by the point the VardDecl is instantiated, which is the last chance we have3486 // of deciding if the candidate is really copy elidable.3487 if ((ReturnType->getTypeClass() == Type::TypeClass::Auto &&3488 ReturnType->isCanonicalUnqualified()) ||3489 ReturnType->isSpecificBuiltinType(BuiltinType::Dependent))3490 return invalidNRVO();3491 3492 if (!ReturnType->isDependentType()) {3493 // - in a return statement in a function with ...3494 // ... a class return type ...3495 if (!ReturnType->isRecordType())3496 return invalidNRVO();3497 3498 QualType VDType = Info.Candidate->getType();3499 // ... the same cv-unqualified type as the function return type ...3500 // When considering moving this expression out, allow dissimilar types.3501 if (!VDType->isDependentType() &&3502 !Context.hasSameUnqualifiedType(ReturnType, VDType))3503 Info.S = NamedReturnInfo::MoveEligible;3504 }3505 return Info.isCopyElidable() ? Info.Candidate : nullptr;3506}3507 3508/// Verify that the initialization sequence that was picked for the3509/// first overload resolution is permissible under C++98.3510///3511/// Reject (possibly converting) constructors not taking an rvalue reference,3512/// or user conversion operators which are not ref-qualified.3513static bool3514VerifyInitializationSequenceCXX98(const Sema &S,3515 const InitializationSequence &Seq) {3516 const auto *Step = llvm::find_if(Seq.steps(), [](const auto &Step) {3517 return Step.Kind == InitializationSequence::SK_ConstructorInitialization ||3518 Step.Kind == InitializationSequence::SK_UserConversion;3519 });3520 if (Step != Seq.step_end()) {3521 const auto *FD = Step->Function.Function;3522 if (isa<CXXConstructorDecl>(FD)3523 ? !FD->getParamDecl(0)->getType()->isRValueReferenceType()3524 : cast<CXXMethodDecl>(FD)->getRefQualifier() == RQ_None)3525 return false;3526 }3527 return true;3528}3529 3530ExprResult Sema::PerformMoveOrCopyInitialization(3531 const InitializedEntity &Entity, const NamedReturnInfo &NRInfo, Expr *Value,3532 bool SupressSimplerImplicitMoves) {3533 if (getLangOpts().CPlusPlus &&3534 (!getLangOpts().CPlusPlus23 || SupressSimplerImplicitMoves) &&3535 NRInfo.isMoveEligible()) {3536 ImplicitCastExpr AsRvalue(ImplicitCastExpr::OnStack, Value->getType(),3537 CK_NoOp, Value, VK_XValue, FPOptionsOverride());3538 Expr *InitExpr = &AsRvalue;3539 auto Kind = InitializationKind::CreateCopy(Value->getBeginLoc(),3540 Value->getBeginLoc());3541 InitializationSequence Seq(*this, Entity, Kind, InitExpr);3542 auto Res = Seq.getFailedOverloadResult();3543 if ((Res == OR_Success || Res == OR_Deleted) &&3544 (getLangOpts().CPlusPlus11 ||3545 VerifyInitializationSequenceCXX98(*this, Seq))) {3546 // Promote "AsRvalue" to the heap, since we now need this3547 // expression node to persist.3548 Value =3549 ImplicitCastExpr::Create(Context, Value->getType(), CK_NoOp, Value,3550 nullptr, VK_XValue, FPOptionsOverride());3551 // Complete type-checking the initialization of the return type3552 // using the constructor we found.3553 return Seq.Perform(*this, Entity, Kind, Value);3554 }3555 }3556 // Either we didn't meet the criteria for treating an lvalue as an rvalue,3557 // above, or overload resolution failed. Either way, we need to try3558 // (again) now with the return value expression as written.3559 return PerformCopyInitialization(Entity, SourceLocation(), Value);3560}3561 3562/// Determine whether the declared return type of the specified function3563/// contains 'auto'.3564static bool hasDeducedReturnType(FunctionDecl *FD) {3565 const FunctionProtoType *FPT =3566 FD->getTypeSourceInfo()->getType()->castAs<FunctionProtoType>();3567 return FPT->getReturnType()->isUndeducedType();3568}3569 3570StmtResult Sema::ActOnCapScopeReturnStmt(SourceLocation ReturnLoc,3571 Expr *RetValExp,3572 NamedReturnInfo &NRInfo,3573 bool SupressSimplerImplicitMoves) {3574 // If this is the first return we've seen, infer the return type.3575 // [expr.prim.lambda]p4 in C++11; block literals follow the same rules.3576 CapturingScopeInfo *CurCap = cast<CapturingScopeInfo>(getCurFunction());3577 QualType FnRetType = CurCap->ReturnType;3578 LambdaScopeInfo *CurLambda = dyn_cast<LambdaScopeInfo>(CurCap);3579 if (CurLambda && CurLambda->CallOperator->getType().isNull())3580 return StmtError();3581 bool HasDeducedReturnType =3582 CurLambda && hasDeducedReturnType(CurLambda->CallOperator);3583 3584 if (ExprEvalContexts.back().isDiscardedStatementContext() &&3585 (HasDeducedReturnType || CurCap->HasImplicitReturnType)) {3586 if (RetValExp) {3587 ExprResult ER =3588 ActOnFinishFullExpr(RetValExp, ReturnLoc, /*DiscardedValue*/ false);3589 if (ER.isInvalid())3590 return StmtError();3591 RetValExp = ER.get();3592 }3593 return ReturnStmt::Create(Context, ReturnLoc, RetValExp,3594 /* NRVOCandidate=*/nullptr);3595 }3596 3597 if (HasDeducedReturnType) {3598 FunctionDecl *FD = CurLambda->CallOperator;3599 // If we've already decided this lambda is invalid, e.g. because3600 // we saw a `return` whose expression had an error, don't keep3601 // trying to deduce its return type.3602 if (FD->isInvalidDecl())3603 return StmtError();3604 // In C++1y, the return type may involve 'auto'.3605 // FIXME: Blocks might have a return type of 'auto' explicitly specified.3606 if (CurCap->ReturnType.isNull())3607 CurCap->ReturnType = FD->getReturnType();3608 3609 AutoType *AT = CurCap->ReturnType->getContainedAutoType();3610 assert(AT && "lost auto type from lambda return type");3611 if (DeduceFunctionTypeFromReturnExpr(FD, ReturnLoc, RetValExp, AT)) {3612 FD->setInvalidDecl();3613 // FIXME: preserve the ill-formed return expression.3614 return StmtError();3615 }3616 CurCap->ReturnType = FnRetType = FD->getReturnType();3617 } else if (CurCap->HasImplicitReturnType) {3618 // For blocks/lambdas with implicit return types, we check each return3619 // statement individually, and deduce the common return type when the block3620 // or lambda is completed.3621 // FIXME: Fold this into the 'auto' codepath above.3622 if (RetValExp && !isa<InitListExpr>(RetValExp)) {3623 ExprResult Result = DefaultFunctionArrayLvalueConversion(RetValExp);3624 if (Result.isInvalid())3625 return StmtError();3626 RetValExp = Result.get();3627 3628 // DR1048: even prior to C++14, we should use the 'auto' deduction rules3629 // when deducing a return type for a lambda-expression (or by extension3630 // for a block). These rules differ from the stated C++11 rules only in3631 // that they remove top-level cv-qualifiers.3632 if (!CurContext->isDependentContext())3633 FnRetType = RetValExp->getType().getUnqualifiedType();3634 else3635 FnRetType = CurCap->ReturnType = Context.DependentTy;3636 } else {3637 if (RetValExp) {3638 // C++11 [expr.lambda.prim]p4 bans inferring the result from an3639 // initializer list, because it is not an expression (even3640 // though we represent it as one). We still deduce 'void'.3641 Diag(ReturnLoc, diag::err_lambda_return_init_list)3642 << RetValExp->getSourceRange();3643 }3644 3645 FnRetType = Context.VoidTy;3646 }3647 3648 // Although we'll properly infer the type of the block once it's completed,3649 // make sure we provide a return type now for better error recovery.3650 if (CurCap->ReturnType.isNull())3651 CurCap->ReturnType = FnRetType;3652 }3653 const VarDecl *NRVOCandidate = getCopyElisionCandidate(NRInfo, FnRetType);3654 3655 if (auto *CurBlock = dyn_cast<BlockScopeInfo>(CurCap)) {3656 if (CurBlock->FunctionType->castAs<FunctionType>()->getNoReturnAttr()) {3657 Diag(ReturnLoc, diag::err_noreturn_has_return_expr)3658 << diag::FalloffFunctionKind::Block;3659 return StmtError();3660 }3661 } else if (auto *CurRegion = dyn_cast<CapturedRegionScopeInfo>(CurCap)) {3662 Diag(ReturnLoc, diag::err_return_in_captured_stmt) << CurRegion->getRegionName();3663 return StmtError();3664 } else {3665 assert(CurLambda && "unknown kind of captured scope");3666 if (CurLambda->CallOperator->getType()3667 ->castAs<FunctionType>()3668 ->getNoReturnAttr()) {3669 Diag(ReturnLoc, diag::err_noreturn_has_return_expr)3670 << diag::FalloffFunctionKind::Lambda;3671 return StmtError();3672 }3673 }3674 3675 // Otherwise, verify that this result type matches the previous one. We are3676 // pickier with blocks than for normal functions because we don't have GCC3677 // compatibility to worry about here.3678 if (FnRetType->isDependentType()) {3679 // Delay processing for now. TODO: there are lots of dependent3680 // types we can conclusively prove aren't void.3681 } else if (FnRetType->isVoidType()) {3682 if (RetValExp && !isa<InitListExpr>(RetValExp) &&3683 !(getLangOpts().CPlusPlus &&3684 (RetValExp->isTypeDependent() ||3685 RetValExp->getType()->isVoidType()))) {3686 if (!getLangOpts().CPlusPlus &&3687 RetValExp->getType()->isVoidType())3688 Diag(ReturnLoc, diag::ext_return_has_void_expr) << "literal" << 2;3689 else {3690 Diag(ReturnLoc, diag::err_return_block_has_expr);3691 RetValExp = nullptr;3692 }3693 }3694 } else if (!RetValExp) {3695 return StmtError(Diag(ReturnLoc, diag::err_block_return_missing_expr));3696 } else if (!RetValExp->isTypeDependent()) {3697 // we have a non-void block with an expression, continue checking3698 3699 // C99 6.8.6.4p3(136): The return statement is not an assignment. The3700 // overlap restriction of subclause 6.5.16.1 does not apply to the case of3701 // function return.3702 3703 // In C++ the return statement is handled via a copy initialization.3704 // the C version of which boils down to CheckSingleAssignmentConstraints.3705 InitializedEntity Entity =3706 InitializedEntity::InitializeResult(ReturnLoc, FnRetType);3707 ExprResult Res = PerformMoveOrCopyInitialization(3708 Entity, NRInfo, RetValExp, SupressSimplerImplicitMoves);3709 if (Res.isInvalid()) {3710 // FIXME: Cleanup temporaries here, anyway?3711 return StmtError();3712 }3713 RetValExp = Res.get();3714 CheckReturnValExpr(RetValExp, FnRetType, ReturnLoc);3715 }3716 3717 if (RetValExp) {3718 ExprResult ER =3719 ActOnFinishFullExpr(RetValExp, ReturnLoc, /*DiscardedValue*/ false);3720 if (ER.isInvalid())3721 return StmtError();3722 RetValExp = ER.get();3723 }3724 auto *Result =3725 ReturnStmt::Create(Context, ReturnLoc, RetValExp, NRVOCandidate);3726 3727 // If we need to check for the named return value optimization,3728 // or if we need to infer the return type,3729 // save the return statement in our scope for later processing.3730 if (CurCap->HasImplicitReturnType || NRVOCandidate)3731 FunctionScopes.back()->Returns.push_back(Result);3732 3733 if (FunctionScopes.back()->FirstReturnLoc.isInvalid())3734 FunctionScopes.back()->FirstReturnLoc = ReturnLoc;3735 3736 if (auto *CurBlock = dyn_cast<BlockScopeInfo>(CurCap);3737 CurBlock && CurCap->HasImplicitReturnType && RetValExp &&3738 RetValExp->containsErrors())3739 CurBlock->TheDecl->setInvalidDecl();3740 3741 return Result;3742}3743 3744namespace {3745/// Marks all typedefs in all local classes in a type referenced.3746///3747/// In a function like3748/// auto f() {3749/// struct S { typedef int a; };3750/// return S();3751/// }3752///3753/// the local type escapes and could be referenced in some TUs but not in3754/// others. Pretend that all local typedefs are always referenced, to not warn3755/// on this. This isn't necessary if f has internal linkage, or the typedef3756/// is private.3757class LocalTypedefNameReferencer : public DynamicRecursiveASTVisitor {3758public:3759 LocalTypedefNameReferencer(Sema &S) : S(S) {}3760 bool VisitRecordType(RecordType *RT) override;3761 3762private:3763 Sema &S;3764};3765bool LocalTypedefNameReferencer::VisitRecordType(RecordType *RT) {3766 auto *R = dyn_cast<CXXRecordDecl>(RT->getDecl());3767 if (!R || !R->isLocalClass() || !R->isLocalClass()->isExternallyVisible() ||3768 R->isDependentType())3769 return true;3770 for (auto *TmpD : R->decls())3771 if (auto *T = dyn_cast<TypedefNameDecl>(TmpD))3772 if (T->getAccess() != AS_private || R->hasFriends())3773 S.MarkAnyDeclReferenced(T->getLocation(), T, /*OdrUse=*/false);3774 return true;3775}3776}3777 3778TypeLoc Sema::getReturnTypeLoc(FunctionDecl *FD) const {3779 return FD->getTypeSourceInfo()3780 ->getTypeLoc()3781 .getAsAdjusted<FunctionProtoTypeLoc>()3782 .getReturnLoc();3783}3784 3785bool Sema::DeduceFunctionTypeFromReturnExpr(FunctionDecl *FD,3786 SourceLocation ReturnLoc,3787 Expr *RetExpr, const AutoType *AT) {3788 // If this is the conversion function for a lambda, we choose to deduce its3789 // type from the corresponding call operator, not from the synthesized return3790 // statement within it. See Sema::DeduceReturnType.3791 if (isLambdaConversionOperator(FD))3792 return false;3793 3794 if (isa_and_nonnull<InitListExpr>(RetExpr)) {3795 // If the deduction is for a return statement and the initializer is3796 // a braced-init-list, the program is ill-formed.3797 Diag(RetExpr->getExprLoc(),3798 getCurLambda() ? diag::err_lambda_return_init_list3799 : diag::err_auto_fn_return_init_list)3800 << RetExpr->getSourceRange();3801 return true;3802 }3803 3804 if (FD->isDependentContext()) {3805 // C++1y [dcl.spec.auto]p12:3806 // Return type deduction [...] occurs when the definition is3807 // instantiated even if the function body contains a return3808 // statement with a non-type-dependent operand.3809 assert(AT->isDeduced() && "should have deduced to dependent type");3810 return false;3811 }3812 3813 TypeLoc OrigResultType = getReturnTypeLoc(FD);3814 // In the case of a return with no operand, the initializer is considered3815 // to be void().3816 CXXScalarValueInitExpr VoidVal(Context.VoidTy, nullptr, SourceLocation());3817 if (!RetExpr) {3818 // For a function with a deduced result type to return with omitted3819 // expression, the result type as written must be 'auto' or3820 // 'decltype(auto)', possibly cv-qualified or constrained, but not3821 // ref-qualified.3822 if (!OrigResultType.getType()->getAs<AutoType>()) {3823 Diag(ReturnLoc, diag::err_auto_fn_return_void_but_not_auto)3824 << OrigResultType.getType();3825 return true;3826 }3827 RetExpr = &VoidVal;3828 }3829 3830 QualType Deduced = AT->getDeducedType();3831 {3832 // Otherwise, [...] deduce a value for U using the rules of template3833 // argument deduction.3834 auto RetExprLoc = RetExpr->getExprLoc();3835 TemplateDeductionInfo Info(RetExprLoc);3836 SourceLocation TemplateSpecLoc;3837 if (RetExpr->getType() == Context.OverloadTy) {3838 auto FindResult = OverloadExpr::find(RetExpr);3839 if (FindResult.Expression)3840 TemplateSpecLoc = FindResult.Expression->getNameLoc();3841 }3842 TemplateSpecCandidateSet FailedTSC(TemplateSpecLoc);3843 TemplateDeductionResult Res = DeduceAutoType(3844 OrigResultType, RetExpr, Deduced, Info, /*DependentDeduction=*/false,3845 /*IgnoreConstraints=*/false, &FailedTSC);3846 if (Res != TemplateDeductionResult::Success && FD->isInvalidDecl())3847 return true;3848 switch (Res) {3849 case TemplateDeductionResult::Success:3850 break;3851 case TemplateDeductionResult::AlreadyDiagnosed:3852 return true;3853 case TemplateDeductionResult::Inconsistent: {3854 // If a function with a declared return type that contains a placeholder3855 // type has multiple return statements, the return type is deduced for3856 // each return statement. [...] if the type deduced is not the same in3857 // each deduction, the program is ill-formed.3858 const LambdaScopeInfo *LambdaSI = getCurLambda();3859 if (LambdaSI && LambdaSI->HasImplicitReturnType)3860 Diag(ReturnLoc, diag::err_typecheck_missing_return_type_incompatible)3861 << Info.SecondArg << Info.FirstArg << true /*IsLambda*/;3862 else3863 Diag(ReturnLoc, diag::err_auto_fn_different_deductions)3864 << (AT->isDecltypeAuto() ? 1 : 0) << Info.SecondArg3865 << Info.FirstArg;3866 return true;3867 }3868 default:3869 Diag(RetExpr->getExprLoc(), diag::err_auto_fn_deduction_failure)3870 << OrigResultType.getType() << RetExpr->getType();3871 FailedTSC.NoteCandidates(*this, RetExprLoc);3872 return true;3873 }3874 }3875 3876 // If a local type is part of the returned type, mark its fields as3877 // referenced.3878 LocalTypedefNameReferencer(*this).TraverseType(RetExpr->getType());3879 3880 // CUDA: Kernel function must have 'void' return type.3881 if (getLangOpts().CUDA && FD->hasAttr<CUDAGlobalAttr>() &&3882 !Deduced->isVoidType()) {3883 Diag(FD->getLocation(), diag::err_kern_type_not_void_return)3884 << FD->getType() << FD->getSourceRange();3885 return true;3886 }3887 3888 if (!FD->isInvalidDecl() && AT->getDeducedType() != Deduced)3889 // Update all declarations of the function to have the deduced return type.3890 Context.adjustDeducedFunctionResultType(FD, Deduced);3891 3892 if (!Deduced->isDependentType() && !Deduced->isRecordType() &&3893 !FD->isFunctionTemplateSpecialization())3894 diagnoseIgnoredQualifiers(3895 diag::warn_qual_return_type,3896 FD->getDeclaredReturnType().getLocalCVRQualifiers(), FD->getLocation());3897 return false;3898}3899 3900StmtResult3901Sema::ActOnReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp,3902 Scope *CurScope) {3903 ExprResult RetVal = RetValExp;3904 if (RetVal.isInvalid())3905 return StmtError();3906 3907 if (getCurScope()->isInOpenACCComputeConstructScope())3908 return StmtError(3909 Diag(ReturnLoc, diag::err_acc_branch_in_out_compute_construct)3910 << /*return*/ 1 << /*out of */ 0);3911 3912 // using plain return in a coroutine is not allowed.3913 FunctionScopeInfo *FSI = getCurFunction();3914 if (FSI->FirstReturnLoc.isInvalid() && FSI->isCoroutine()) {3915 assert(FSI->FirstCoroutineStmtLoc.isValid() &&3916 "first coroutine location not set");3917 Diag(ReturnLoc, diag::err_return_in_coroutine);3918 Diag(FSI->FirstCoroutineStmtLoc, diag::note_declared_coroutine_here)3919 << FSI->getFirstCoroutineStmtKeyword();3920 }3921 3922 CheckInvalidBuiltinCountedByRef(RetVal.get(),3923 BuiltinCountedByRefKind::ReturnArg);3924 3925 StmtResult R =3926 BuildReturnStmt(ReturnLoc, RetVal.get(), /*AllowRecovery=*/true);3927 if (R.isInvalid() || ExprEvalContexts.back().isDiscardedStatementContext())3928 return R;3929 3930 VarDecl *VD =3931 const_cast<VarDecl *>(cast<ReturnStmt>(R.get())->getNRVOCandidate());3932 3933 CurScope->updateNRVOCandidate(VD);3934 3935 CheckJumpOutOfSEHFinally(*this, ReturnLoc, *CurScope->getFnParent());3936 3937 return R;3938}3939 3940static bool CheckSimplerImplicitMovesMSVCWorkaround(const Sema &S,3941 const Expr *E) {3942 if (!E || !S.getLangOpts().CPlusPlus23 || !S.getLangOpts().MSVCCompat)3943 return false;3944 const Decl *D = E->getReferencedDeclOfCallee();3945 if (!D || !S.SourceMgr.isInSystemHeader(D->getLocation()))3946 return false;3947 for (const DeclContext *DC = D->getDeclContext(); DC; DC = DC->getParent()) {3948 if (DC->isStdNamespace())3949 return true;3950 }3951 return false;3952}3953 3954StmtResult Sema::BuildReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp,3955 bool AllowRecovery) {3956 // Check for unexpanded parameter packs.3957 if (RetValExp && DiagnoseUnexpandedParameterPack(RetValExp))3958 return StmtError();3959 3960 // HACK: We suppress simpler implicit move here in msvc compatibility mode3961 // just as a temporary work around, as the MSVC STL has issues with3962 // this change.3963 bool SupressSimplerImplicitMoves =3964 CheckSimplerImplicitMovesMSVCWorkaround(*this, RetValExp);3965 NamedReturnInfo NRInfo = getNamedReturnInfo(3966 RetValExp, SupressSimplerImplicitMoves ? SimplerImplicitMoveMode::ForceOff3967 : SimplerImplicitMoveMode::Normal);3968 3969 if (isa<CapturingScopeInfo>(getCurFunction()))3970 return ActOnCapScopeReturnStmt(ReturnLoc, RetValExp, NRInfo,3971 SupressSimplerImplicitMoves);3972 3973 QualType FnRetType;3974 QualType RelatedRetType;3975 const AttrVec *Attrs = nullptr;3976 bool isObjCMethod = false;3977 3978 if (const FunctionDecl *FD = getCurFunctionDecl()) {3979 FnRetType = FD->getReturnType();3980 if (FD->hasAttrs())3981 Attrs = &FD->getAttrs();3982 if (FD->isNoReturn() && !getCurFunction()->isCoroutine())3983 Diag(ReturnLoc, diag::warn_noreturn_function_has_return_expr) << FD;3984 if (FD->isMain() && RetValExp)3985 if (isa<CXXBoolLiteralExpr>(RetValExp))3986 Diag(ReturnLoc, diag::warn_main_returns_bool_literal)3987 << RetValExp->getSourceRange();3988 if (FD->hasAttr<CmseNSEntryAttr>() && RetValExp) {3989 if (const auto *RT = dyn_cast<RecordType>(FnRetType.getCanonicalType())) {3990 if (RT->getDecl()->isOrContainsUnion())3991 Diag(RetValExp->getBeginLoc(), diag::warn_cmse_nonsecure_union) << 1;3992 }3993 }3994 } else if (ObjCMethodDecl *MD = getCurMethodDecl()) {3995 FnRetType = MD->getReturnType();3996 isObjCMethod = true;3997 if (MD->hasAttrs())3998 Attrs = &MD->getAttrs();3999 if (MD->hasRelatedResultType() && MD->getClassInterface()) {4000 // In the implementation of a method with a related return type, the4001 // type used to type-check the validity of return statements within the4002 // method body is a pointer to the type of the class being implemented.4003 RelatedRetType = Context.getObjCInterfaceType(MD->getClassInterface());4004 RelatedRetType = Context.getObjCObjectPointerType(RelatedRetType);4005 }4006 } else // If we don't have a function/method context, bail.4007 return StmtError();4008 4009 if (RetValExp) {4010 const auto *ATy = dyn_cast<ArrayType>(RetValExp->getType());4011 if (ATy && ATy->getElementType().isWebAssemblyReferenceType()) {4012 Diag(ReturnLoc, diag::err_wasm_table_art) << 1;4013 return StmtError();4014 }4015 }4016 4017 // C++1z: discarded return statements are not considered when deducing a4018 // return type.4019 if (ExprEvalContexts.back().isDiscardedStatementContext() &&4020 FnRetType->getContainedAutoType()) {4021 if (RetValExp) {4022 ExprResult ER =4023 ActOnFinishFullExpr(RetValExp, ReturnLoc, /*DiscardedValue*/ false);4024 if (ER.isInvalid())4025 return StmtError();4026 RetValExp = ER.get();4027 }4028 return ReturnStmt::Create(Context, ReturnLoc, RetValExp,4029 /* NRVOCandidate=*/nullptr);4030 }4031 4032 // FIXME: Add a flag to the ScopeInfo to indicate whether we're performing4033 // deduction.4034 if (getLangOpts().CPlusPlus14) {4035 if (AutoType *AT = FnRetType->getContainedAutoType()) {4036 FunctionDecl *FD = cast<FunctionDecl>(CurContext);4037 // If we've already decided this function is invalid, e.g. because4038 // we saw a `return` whose expression had an error, don't keep4039 // trying to deduce its return type.4040 // (Some return values may be needlessly wrapped in RecoveryExpr).4041 if (FD->isInvalidDecl() ||4042 DeduceFunctionTypeFromReturnExpr(FD, ReturnLoc, RetValExp, AT)) {4043 FD->setInvalidDecl();4044 if (!AllowRecovery)4045 return StmtError();4046 // The deduction failure is diagnosed and marked, try to recover.4047 if (RetValExp) {4048 // Wrap return value with a recovery expression of the previous type.4049 // If no deduction yet, use DependentTy.4050 auto Recovery = CreateRecoveryExpr(4051 RetValExp->getBeginLoc(), RetValExp->getEndLoc(), RetValExp,4052 AT->isDeduced() ? FnRetType : QualType());4053 if (Recovery.isInvalid())4054 return StmtError();4055 RetValExp = Recovery.get();4056 } else {4057 // Nothing to do: a ReturnStmt with no value is fine recovery.4058 }4059 } else {4060 FnRetType = FD->getReturnType();4061 }4062 }4063 }4064 const VarDecl *NRVOCandidate = getCopyElisionCandidate(NRInfo, FnRetType);4065 4066 bool HasDependentReturnType = FnRetType->isDependentType();4067 4068 ReturnStmt *Result = nullptr;4069 if (FnRetType->isVoidType()) {4070 if (RetValExp) {4071 if (auto *ILE = dyn_cast<InitListExpr>(RetValExp)) {4072 // We simply never allow init lists as the return value of void4073 // functions. This is compatible because this was never allowed before,4074 // so there's no legacy code to deal with.4075 NamedDecl *CurDecl = getCurFunctionOrMethodDecl();4076 int FunctionKind = 0;4077 if (isa<ObjCMethodDecl>(CurDecl))4078 FunctionKind = 1;4079 else if (isa<CXXConstructorDecl>(CurDecl))4080 FunctionKind = 2;4081 else if (isa<CXXDestructorDecl>(CurDecl))4082 FunctionKind = 3;4083 4084 Diag(ReturnLoc, diag::err_return_init_list)4085 << CurDecl << FunctionKind << RetValExp->getSourceRange();4086 4087 // Preserve the initializers in the AST.4088 RetValExp = AllowRecovery4089 ? CreateRecoveryExpr(ILE->getLBraceLoc(),4090 ILE->getRBraceLoc(), ILE->inits())4091 .get()4092 : nullptr;4093 } else if (!RetValExp->isTypeDependent()) {4094 // C99 6.8.6.4p1 (ext_ since GCC warns)4095 unsigned D = diag::ext_return_has_expr;4096 if (RetValExp->getType()->isVoidType()) {4097 NamedDecl *CurDecl = getCurFunctionOrMethodDecl();4098 if (isa<CXXConstructorDecl>(CurDecl) ||4099 isa<CXXDestructorDecl>(CurDecl))4100 D = diag::err_ctor_dtor_returns_void;4101 else4102 D = diag::ext_return_has_void_expr;4103 }4104 else {4105 ExprResult Result = RetValExp;4106 Result = IgnoredValueConversions(Result.get());4107 if (Result.isInvalid())4108 return StmtError();4109 RetValExp = Result.get();4110 RetValExp = ImpCastExprToType(RetValExp,4111 Context.VoidTy, CK_ToVoid).get();4112 }4113 // return of void in constructor/destructor is illegal in C++.4114 if (D == diag::err_ctor_dtor_returns_void) {4115 NamedDecl *CurDecl = getCurFunctionOrMethodDecl();4116 Diag(ReturnLoc, D) << CurDecl << isa<CXXDestructorDecl>(CurDecl)4117 << RetValExp->getSourceRange();4118 }4119 // return (some void expression); is legal in C++ and C2y.4120 else if (D != diag::ext_return_has_void_expr ||4121 (!getLangOpts().CPlusPlus && !getLangOpts().C2y)) {4122 NamedDecl *CurDecl = getCurFunctionOrMethodDecl();4123 4124 int FunctionKind = 0;4125 if (isa<ObjCMethodDecl>(CurDecl))4126 FunctionKind = 1;4127 else if (isa<CXXConstructorDecl>(CurDecl))4128 FunctionKind = 2;4129 else if (isa<CXXDestructorDecl>(CurDecl))4130 FunctionKind = 3;4131 4132 Diag(ReturnLoc, D)4133 << CurDecl << FunctionKind << RetValExp->getSourceRange();4134 }4135 }4136 4137 if (RetValExp) {4138 ExprResult ER =4139 ActOnFinishFullExpr(RetValExp, ReturnLoc, /*DiscardedValue*/ false);4140 if (ER.isInvalid())4141 return StmtError();4142 RetValExp = ER.get();4143 }4144 }4145 4146 Result = ReturnStmt::Create(Context, ReturnLoc, RetValExp,4147 /* NRVOCandidate=*/nullptr);4148 } else if (!RetValExp && !HasDependentReturnType) {4149 FunctionDecl *FD = getCurFunctionDecl();4150 4151 if ((FD && FD->isInvalidDecl()) || FnRetType->containsErrors()) {4152 // The intended return type might have been "void", so don't warn.4153 } else if (getLangOpts().CPlusPlus11 && FD && FD->isConstexpr()) {4154 // C++11 [stmt.return]p24155 Diag(ReturnLoc, diag::err_constexpr_return_missing_expr)4156 << FD << FD->isConsteval();4157 FD->setInvalidDecl();4158 } else {4159 // C99 6.8.6.4p1 (ext_ since GCC warns)4160 // C90 6.6.6.4p44161 unsigned DiagID = getLangOpts().C99 ? diag::ext_return_missing_expr4162 : diag::warn_return_missing_expr;4163 // Note that at this point one of getCurFunctionDecl() or4164 // getCurMethodDecl() must be non-null (see above).4165 assert((getCurFunctionDecl() || getCurMethodDecl()) &&4166 "Not in a FunctionDecl or ObjCMethodDecl?");4167 bool IsMethod = FD == nullptr;4168 const NamedDecl *ND =4169 IsMethod ? cast<NamedDecl>(getCurMethodDecl()) : cast<NamedDecl>(FD);4170 Diag(ReturnLoc, DiagID) << ND << IsMethod;4171 }4172 4173 Result = ReturnStmt::Create(Context, ReturnLoc, /* RetExpr=*/nullptr,4174 /* NRVOCandidate=*/nullptr);4175 } else {4176 assert(RetValExp || HasDependentReturnType);4177 QualType RetType = RelatedRetType.isNull() ? FnRetType : RelatedRetType;4178 4179 // C99 6.8.6.4p3(136): The return statement is not an assignment. The4180 // overlap restriction of subclause 6.5.16.1 does not apply to the case of4181 // function return.4182 4183 // In C++ the return statement is handled via a copy initialization,4184 // the C version of which boils down to CheckSingleAssignmentConstraints.4185 if (!HasDependentReturnType && !RetValExp->isTypeDependent()) {4186 // we have a non-void function with an expression, continue checking4187 InitializedEntity Entity =4188 InitializedEntity::InitializeResult(ReturnLoc, RetType);4189 ExprResult Res = PerformMoveOrCopyInitialization(4190 Entity, NRInfo, RetValExp, SupressSimplerImplicitMoves);4191 if (Res.isInvalid() && AllowRecovery)4192 Res = CreateRecoveryExpr(RetValExp->getBeginLoc(),4193 RetValExp->getEndLoc(), RetValExp, RetType);4194 if (Res.isInvalid()) {4195 // FIXME: Clean up temporaries here anyway?4196 return StmtError();4197 }4198 RetValExp = Res.getAs<Expr>();4199 4200 // If we have a related result type, we need to implicitly4201 // convert back to the formal result type. We can't pretend to4202 // initialize the result again --- we might end double-retaining4203 // --- so instead we initialize a notional temporary.4204 if (!RelatedRetType.isNull()) {4205 Entity = InitializedEntity::InitializeRelatedResult(getCurMethodDecl(),4206 FnRetType);4207 Res = PerformCopyInitialization(Entity, ReturnLoc, RetValExp);4208 if (Res.isInvalid()) {4209 // FIXME: Clean up temporaries here anyway?4210 return StmtError();4211 }4212 RetValExp = Res.getAs<Expr>();4213 }4214 4215 CheckReturnValExpr(RetValExp, FnRetType, ReturnLoc, isObjCMethod, Attrs,4216 getCurFunctionDecl());4217 }4218 4219 if (RetValExp) {4220 ExprResult ER =4221 ActOnFinishFullExpr(RetValExp, ReturnLoc, /*DiscardedValue*/ false);4222 if (ER.isInvalid())4223 return StmtError();4224 RetValExp = ER.get();4225 }4226 Result = ReturnStmt::Create(Context, ReturnLoc, RetValExp, NRVOCandidate);4227 }4228 4229 // If we need to check for the named return value optimization, save the4230 // return statement in our scope for later processing.4231 if (Result->getNRVOCandidate())4232 FunctionScopes.back()->Returns.push_back(Result);4233 4234 if (FunctionScopes.back()->FirstReturnLoc.isInvalid())4235 FunctionScopes.back()->FirstReturnLoc = ReturnLoc;4236 4237 return Result;4238}4239 4240StmtResult4241Sema::ActOnCXXCatchBlock(SourceLocation CatchLoc, Decl *ExDecl,4242 Stmt *HandlerBlock) {4243 // There's nothing to test that ActOnExceptionDecl didn't already test.4244 return new (Context)4245 CXXCatchStmt(CatchLoc, cast_or_null<VarDecl>(ExDecl), HandlerBlock);4246}4247 4248namespace {4249class CatchHandlerType {4250 QualType QT;4251 LLVM_PREFERRED_TYPE(bool)4252 unsigned IsPointer : 1;4253 4254 // This is a special constructor to be used only with DenseMapInfo's4255 // getEmptyKey() and getTombstoneKey() functions.4256 friend struct llvm::DenseMapInfo<CatchHandlerType>;4257 enum Unique { ForDenseMap };4258 CatchHandlerType(QualType QT, Unique) : QT(QT), IsPointer(false) {}4259 4260public:4261 /// Used when creating a CatchHandlerType from a handler type; will determine4262 /// whether the type is a pointer or reference and will strip off the top4263 /// level pointer and cv-qualifiers.4264 CatchHandlerType(QualType Q) : QT(Q), IsPointer(false) {4265 if (QT->isPointerType())4266 IsPointer = true;4267 4268 QT = QT.getUnqualifiedType();4269 if (IsPointer || QT->isReferenceType())4270 QT = QT->getPointeeType();4271 }4272 4273 /// Used when creating a CatchHandlerType from a base class type; pretends the4274 /// type passed in had the pointer qualifier, does not need to get an4275 /// unqualified type.4276 CatchHandlerType(QualType QT, bool IsPointer)4277 : QT(QT), IsPointer(IsPointer) {}4278 4279 QualType underlying() const { return QT; }4280 bool isPointer() const { return IsPointer; }4281 4282 friend bool operator==(const CatchHandlerType &LHS,4283 const CatchHandlerType &RHS) {4284 // If the pointer qualification does not match, we can return early.4285 if (LHS.IsPointer != RHS.IsPointer)4286 return false;4287 // Otherwise, check the underlying type without cv-qualifiers.4288 return LHS.QT == RHS.QT;4289 }4290};4291} // namespace4292 4293namespace llvm {4294template <> struct DenseMapInfo<CatchHandlerType> {4295 static CatchHandlerType getEmptyKey() {4296 return CatchHandlerType(DenseMapInfo<QualType>::getEmptyKey(),4297 CatchHandlerType::ForDenseMap);4298 }4299 4300 static CatchHandlerType getTombstoneKey() {4301 return CatchHandlerType(DenseMapInfo<QualType>::getTombstoneKey(),4302 CatchHandlerType::ForDenseMap);4303 }4304 4305 static unsigned getHashValue(const CatchHandlerType &Base) {4306 return DenseMapInfo<QualType>::getHashValue(Base.underlying());4307 }4308 4309 static bool isEqual(const CatchHandlerType &LHS,4310 const CatchHandlerType &RHS) {4311 return LHS == RHS;4312 }4313};4314}4315 4316namespace {4317class CatchTypePublicBases {4318 const llvm::DenseMap<QualType, CXXCatchStmt *> &TypesToCheck;4319 4320 CXXCatchStmt *FoundHandler;4321 QualType FoundHandlerType;4322 QualType TestAgainstType;4323 4324public:4325 CatchTypePublicBases(const llvm::DenseMap<QualType, CXXCatchStmt *> &T,4326 QualType QT)4327 : TypesToCheck(T), FoundHandler(nullptr), TestAgainstType(QT) {}4328 4329 CXXCatchStmt *getFoundHandler() const { return FoundHandler; }4330 QualType getFoundHandlerType() const { return FoundHandlerType; }4331 4332 bool operator()(const CXXBaseSpecifier *S, CXXBasePath &) {4333 if (S->getAccessSpecifier() == AccessSpecifier::AS_public) {4334 QualType Check = S->getType().getCanonicalType();4335 const auto &M = TypesToCheck;4336 auto I = M.find(Check);4337 if (I != M.end()) {4338 // We're pretty sure we found what we need to find. However, we still4339 // need to make sure that we properly compare for pointers and4340 // references, to handle cases like:4341 //4342 // } catch (Base *b) {4343 // } catch (Derived &d) {4344 // }4345 //4346 // where there is a qualification mismatch that disqualifies this4347 // handler as a potential problem.4348 if (I->second->getCaughtType()->isPointerType() ==4349 TestAgainstType->isPointerType()) {4350 FoundHandler = I->second;4351 FoundHandlerType = Check;4352 return true;4353 }4354 }4355 }4356 return false;4357 }4358};4359}4360 4361StmtResult Sema::ActOnCXXTryBlock(SourceLocation TryLoc, Stmt *TryBlock,4362 ArrayRef<Stmt *> Handlers) {4363 const llvm::Triple &T = Context.getTargetInfo().getTriple();4364 const bool IsOpenMPGPUTarget =4365 getLangOpts().OpenMPIsTargetDevice && T.isGPU();4366 4367 DiagnoseExceptionUse(TryLoc, /* IsTry= */ true);4368 4369 // In OpenMP target regions, we assume that catch is never reached on GPU4370 // targets.4371 if (IsOpenMPGPUTarget)4372 targetDiag(TryLoc, diag::warn_try_not_valid_on_target) << T.str();4373 4374 // Exceptions aren't allowed in CUDA device code.4375 if (getLangOpts().CUDA)4376 CUDA().DiagIfDeviceCode(TryLoc, diag::err_cuda_device_exceptions)4377 << "try" << CUDA().CurrentTarget();4378 4379 if (getCurScope() && getCurScope()->isOpenMPSimdDirectiveScope())4380 Diag(TryLoc, diag::err_omp_simd_region_cannot_use_stmt) << "try";4381 4382 sema::FunctionScopeInfo *FSI = getCurFunction();4383 4384 // C++ try is incompatible with SEH __try.4385 if (!getLangOpts().Borland && FSI->FirstSEHTryLoc.isValid()) {4386 Diag(TryLoc, diag::err_mixing_cxx_try_seh_try) << 0;4387 Diag(FSI->FirstSEHTryLoc, diag::note_conflicting_try_here) << "'__try'";4388 }4389 4390 const unsigned NumHandlers = Handlers.size();4391 assert(!Handlers.empty() &&4392 "The parser shouldn't call this if there are no handlers.");4393 4394 llvm::DenseMap<QualType, CXXCatchStmt *> HandledBaseTypes;4395 llvm::DenseMap<CatchHandlerType, CXXCatchStmt *> HandledTypes;4396 for (unsigned i = 0; i < NumHandlers; ++i) {4397 CXXCatchStmt *H = cast<CXXCatchStmt>(Handlers[i]);4398 4399 // Diagnose when the handler is a catch-all handler, but it isn't the last4400 // handler for the try block. [except.handle]p5. Also, skip exception4401 // declarations that are invalid, since we can't usefully report on them.4402 if (!H->getExceptionDecl()) {4403 if (i < NumHandlers - 1)4404 return StmtError(Diag(H->getBeginLoc(), diag::err_early_catch_all));4405 continue;4406 } else if (H->getExceptionDecl()->isInvalidDecl())4407 continue;4408 4409 // Walk the type hierarchy to diagnose when this type has already been4410 // handled (duplication), or cannot be handled (derivation inversion). We4411 // ignore top-level cv-qualifiers, per [except.handle]p34412 CatchHandlerType HandlerCHT = H->getCaughtType().getCanonicalType();4413 4414 // We can ignore whether the type is a reference or a pointer; we need the4415 // underlying declaration type in order to get at the underlying record4416 // decl, if there is one.4417 QualType Underlying = HandlerCHT.underlying();4418 if (auto *RD = Underlying->getAsCXXRecordDecl()) {4419 if (!RD->hasDefinition())4420 continue;4421 // Check that none of the public, unambiguous base classes are in the4422 // map ([except.handle]p1). Give the base classes the same pointer4423 // qualification as the original type we are basing off of. This allows4424 // comparison against the handler type using the same top-level pointer4425 // as the original type.4426 CXXBasePaths Paths;4427 Paths.setOrigin(RD);4428 CatchTypePublicBases CTPB(HandledBaseTypes,4429 H->getCaughtType().getCanonicalType());4430 if (RD->lookupInBases(CTPB, Paths)) {4431 const CXXCatchStmt *Problem = CTPB.getFoundHandler();4432 if (!Paths.isAmbiguous(4433 CanQualType::CreateUnsafe(CTPB.getFoundHandlerType()))) {4434 Diag(H->getExceptionDecl()->getTypeSpecStartLoc(),4435 diag::warn_exception_caught_by_earlier_handler)4436 << H->getCaughtType();4437 Diag(Problem->getExceptionDecl()->getTypeSpecStartLoc(),4438 diag::note_previous_exception_handler)4439 << Problem->getCaughtType();4440 }4441 }4442 // Strip the qualifiers here because we're going to be comparing this4443 // type to the base type specifiers of a class, which are ignored in a4444 // base specifier per [class.derived.general]p2.4445 HandledBaseTypes[Underlying.getUnqualifiedType()] = H;4446 }4447 4448 // Add the type the list of ones we have handled; diagnose if we've already4449 // handled it.4450 auto R = HandledTypes.insert(4451 std::make_pair(H->getCaughtType().getCanonicalType(), H));4452 if (!R.second) {4453 const CXXCatchStmt *Problem = R.first->second;4454 Diag(H->getExceptionDecl()->getTypeSpecStartLoc(),4455 diag::warn_exception_caught_by_earlier_handler)4456 << H->getCaughtType();4457 Diag(Problem->getExceptionDecl()->getTypeSpecStartLoc(),4458 diag::note_previous_exception_handler)4459 << Problem->getCaughtType();4460 }4461 }4462 4463 FSI->setHasCXXTry(TryLoc);4464 4465 return CXXTryStmt::Create(Context, TryLoc, cast<CompoundStmt>(TryBlock),4466 Handlers);4467}4468 4469void Sema::DiagnoseExceptionUse(SourceLocation Loc, bool IsTry) {4470 const llvm::Triple &T = Context.getTargetInfo().getTriple();4471 const bool IsOpenMPGPUTarget =4472 getLangOpts().OpenMPIsTargetDevice && T.isGPU();4473 4474 // Don't report an error if 'try' is used in system headers or in an OpenMP4475 // target region compiled for a GPU architecture.4476 if (IsOpenMPGPUTarget || getLangOpts().CUDA)4477 // Delay error emission for the OpenMP device code.4478 return;4479 4480 if (!getLangOpts().CXXExceptions &&4481 !getSourceManager().isInSystemHeader(Loc) &&4482 !CurContext->isDependentContext())4483 targetDiag(Loc, diag::err_exceptions_disabled) << (IsTry ? "try" : "throw");4484}4485 4486StmtResult Sema::ActOnSEHTryBlock(bool IsCXXTry, SourceLocation TryLoc,4487 Stmt *TryBlock, Stmt *Handler) {4488 assert(TryBlock && Handler);4489 4490 sema::FunctionScopeInfo *FSI = getCurFunction();4491 4492 // SEH __try is incompatible with C++ try. Borland appears to support this,4493 // however.4494 if (!getLangOpts().Borland) {4495 if (FSI->FirstCXXOrObjCTryLoc.isValid()) {4496 Diag(TryLoc, diag::err_mixing_cxx_try_seh_try) << FSI->FirstTryType;4497 Diag(FSI->FirstCXXOrObjCTryLoc, diag::note_conflicting_try_here)4498 << (FSI->FirstTryType == sema::FunctionScopeInfo::TryLocIsCXX4499 ? "'try'"4500 : "'@try'");4501 }4502 }4503 4504 FSI->setHasSEHTry(TryLoc);4505 4506 // Reject __try in Obj-C methods, blocks, and captured decls, since we don't4507 // track if they use SEH.4508 DeclContext *DC = CurContext;4509 while (DC && !DC->isFunctionOrMethod())4510 DC = DC->getParent();4511 FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(DC);4512 if (FD)4513 FD->setUsesSEHTry(true);4514 else4515 Diag(TryLoc, diag::err_seh_try_outside_functions);4516 4517 // Reject __try on unsupported targets.4518 if (!Context.getTargetInfo().isSEHTrySupported())4519 Diag(TryLoc, diag::err_seh_try_unsupported);4520 4521 return SEHTryStmt::Create(Context, IsCXXTry, TryLoc, TryBlock, Handler);4522}4523 4524StmtResult Sema::ActOnSEHExceptBlock(SourceLocation Loc, Expr *FilterExpr,4525 Stmt *Block) {4526 assert(FilterExpr && Block);4527 QualType FTy = FilterExpr->getType();4528 if (!FTy->isIntegerType() && !FTy->isDependentType()) {4529 return StmtError(4530 Diag(FilterExpr->getExprLoc(), diag::err_filter_expression_integral)4531 << FTy);4532 }4533 return SEHExceptStmt::Create(Context, Loc, FilterExpr, Block);4534}4535 4536void Sema::ActOnStartSEHFinallyBlock() {4537 CurrentSEHFinally.push_back(CurScope);4538}4539 4540void Sema::ActOnAbortSEHFinallyBlock() {4541 CurrentSEHFinally.pop_back();4542}4543 4544StmtResult Sema::ActOnFinishSEHFinallyBlock(SourceLocation Loc, Stmt *Block) {4545 assert(Block);4546 CurrentSEHFinally.pop_back();4547 return SEHFinallyStmt::Create(Context, Loc, Block);4548}4549 4550StmtResult4551Sema::ActOnSEHLeaveStmt(SourceLocation Loc, Scope *CurScope) {4552 Scope *SEHTryParent = CurScope;4553 while (SEHTryParent && !SEHTryParent->isSEHTryScope())4554 SEHTryParent = SEHTryParent->getParent();4555 if (!SEHTryParent)4556 return StmtError(Diag(Loc, diag::err_ms___leave_not_in___try));4557 CheckJumpOutOfSEHFinally(*this, Loc, *SEHTryParent);4558 4559 return new (Context) SEHLeaveStmt(Loc);4560}4561 4562StmtResult Sema::BuildMSDependentExistsStmt(SourceLocation KeywordLoc,4563 bool IsIfExists,4564 NestedNameSpecifierLoc QualifierLoc,4565 DeclarationNameInfo NameInfo,4566 Stmt *Nested)4567{4568 return new (Context) MSDependentExistsStmt(KeywordLoc, IsIfExists,4569 QualifierLoc, NameInfo,4570 cast<CompoundStmt>(Nested));4571}4572 4573 4574StmtResult Sema::ActOnMSDependentExistsStmt(SourceLocation KeywordLoc,4575 bool IsIfExists,4576 CXXScopeSpec &SS,4577 UnqualifiedId &Name,4578 Stmt *Nested) {4579 return BuildMSDependentExistsStmt(KeywordLoc, IsIfExists,4580 SS.getWithLocInContext(Context),4581 GetNameFromUnqualifiedId(Name),4582 Nested);4583}4584 4585RecordDecl*4586Sema::CreateCapturedStmtRecordDecl(CapturedDecl *&CD, SourceLocation Loc,4587 unsigned NumParams) {4588 DeclContext *DC = CurContext;4589 while (!(DC->isFunctionOrMethod() || DC->isRecord() || DC->isFileContext()))4590 DC = DC->getParent();4591 4592 RecordDecl *RD = nullptr;4593 if (getLangOpts().CPlusPlus)4594 RD = CXXRecordDecl::Create(Context, TagTypeKind::Struct, DC, Loc, Loc,4595 /*Id=*/nullptr);4596 else4597 RD = RecordDecl::Create(Context, TagTypeKind::Struct, DC, Loc, Loc,4598 /*Id=*/nullptr);4599 4600 RD->setCapturedRecord();4601 DC->addDecl(RD);4602 RD->setImplicit();4603 RD->startDefinition();4604 4605 assert(NumParams > 0 && "CapturedStmt requires context parameter");4606 CD = CapturedDecl::Create(Context, CurContext, NumParams);4607 DC->addDecl(CD);4608 return RD;4609}4610 4611static bool4612buildCapturedStmtCaptureList(Sema &S, CapturedRegionScopeInfo *RSI,4613 SmallVectorImpl<CapturedStmt::Capture> &Captures,4614 SmallVectorImpl<Expr *> &CaptureInits) {4615 for (const sema::Capture &Cap : RSI->Captures) {4616 if (Cap.isInvalid())4617 continue;4618 4619 // Form the initializer for the capture.4620 ExprResult Init = S.BuildCaptureInit(Cap, Cap.getLocation(),4621 RSI->CapRegionKind == CR_OpenMP);4622 4623 // FIXME: Bail out now if the capture is not used and the initializer has4624 // no side-effects.4625 4626 // Create a field for this capture.4627 FieldDecl *Field = S.BuildCaptureField(RSI->TheRecordDecl, Cap);4628 4629 // Add the capture to our list of captures.4630 if (Cap.isThisCapture()) {4631 Captures.push_back(CapturedStmt::Capture(Cap.getLocation(),4632 CapturedStmt::VCK_This));4633 } else if (Cap.isVLATypeCapture()) {4634 Captures.push_back(4635 CapturedStmt::Capture(Cap.getLocation(), CapturedStmt::VCK_VLAType));4636 } else {4637 assert(Cap.isVariableCapture() && "unknown kind of capture");4638 4639 if (S.getLangOpts().OpenMP && RSI->CapRegionKind == CR_OpenMP)4640 S.OpenMP().setOpenMPCaptureKind(Field, Cap.getVariable(),4641 RSI->OpenMPLevel);4642 4643 Captures.push_back(CapturedStmt::Capture(4644 Cap.getLocation(),4645 Cap.isReferenceCapture() ? CapturedStmt::VCK_ByRef4646 : CapturedStmt::VCK_ByCopy,4647 cast<VarDecl>(Cap.getVariable())));4648 }4649 CaptureInits.push_back(Init.get());4650 }4651 return false;4652}4653 4654static std::optional<int>4655isOpenMPCapturedRegionInArmSMEFunction(Sema const &S, CapturedRegionKind Kind) {4656 if (!S.getLangOpts().OpenMP || Kind != CR_OpenMP)4657 return {};4658 if (const FunctionDecl *FD = S.getCurFunctionDecl(/*AllowLambda=*/true)) {4659 if (IsArmStreamingFunction(FD, /*IncludeLocallyStreaming=*/true))4660 return /* in streaming functions */ 0;4661 if (hasArmZAState(FD))4662 return /* in functions with ZA state */ 1;4663 if (hasArmZT0State(FD))4664 return /* in fuctions with ZT0 state */ 2;4665 }4666 return {};4667}4668 4669void Sema::ActOnCapturedRegionStart(SourceLocation Loc, Scope *CurScope,4670 CapturedRegionKind Kind,4671 unsigned NumParams) {4672 if (auto ErrorIndex = isOpenMPCapturedRegionInArmSMEFunction(*this, Kind))4673 Diag(Loc, diag::err_sme_openmp_captured_region) << *ErrorIndex;4674 4675 CapturedDecl *CD = nullptr;4676 RecordDecl *RD = CreateCapturedStmtRecordDecl(CD, Loc, NumParams);4677 4678 // Build the context parameter4679 DeclContext *DC = CapturedDecl::castToDeclContext(CD);4680 IdentifierInfo *ParamName = &Context.Idents.get("__context");4681 CanQualType ParamType =4682 Context.getPointerType(Context.getCanonicalTagType(RD));4683 auto *Param =4684 ImplicitParamDecl::Create(Context, DC, Loc, ParamName, ParamType,4685 ImplicitParamKind::CapturedContext);4686 DC->addDecl(Param);4687 4688 CD->setContextParam(0, Param);4689 4690 // Enter the capturing scope for this captured region.4691 PushCapturedRegionScope(CurScope, CD, RD, Kind);4692 4693 if (CurScope)4694 PushDeclContext(CurScope, CD);4695 else4696 CurContext = CD;4697 4698 PushExpressionEvaluationContext(4699 ExpressionEvaluationContext::PotentiallyEvaluated);4700 ExprEvalContexts.back().InImmediateEscalatingFunctionContext = false;4701}4702 4703void Sema::ActOnCapturedRegionStart(SourceLocation Loc, Scope *CurScope,4704 CapturedRegionKind Kind,4705 ArrayRef<CapturedParamNameType> Params,4706 unsigned OpenMPCaptureLevel) {4707 if (auto ErrorIndex = isOpenMPCapturedRegionInArmSMEFunction(*this, Kind))4708 Diag(Loc, diag::err_sme_openmp_captured_region) << *ErrorIndex;4709 4710 CapturedDecl *CD = nullptr;4711 RecordDecl *RD = CreateCapturedStmtRecordDecl(CD, Loc, Params.size());4712 4713 // Build the context parameter4714 DeclContext *DC = CapturedDecl::castToDeclContext(CD);4715 bool ContextIsFound = false;4716 unsigned ParamNum = 0;4717 for (ArrayRef<CapturedParamNameType>::iterator I = Params.begin(),4718 E = Params.end();4719 I != E; ++I, ++ParamNum) {4720 if (I->second.isNull()) {4721 assert(!ContextIsFound &&4722 "null type has been found already for '__context' parameter");4723 IdentifierInfo *ParamName = &Context.Idents.get("__context");4724 QualType ParamType =4725 Context.getPointerType(Context.getCanonicalTagType(RD))4726 .withConst()4727 .withRestrict();4728 auto *Param =4729 ImplicitParamDecl::Create(Context, DC, Loc, ParamName, ParamType,4730 ImplicitParamKind::CapturedContext);4731 DC->addDecl(Param);4732 CD->setContextParam(ParamNum, Param);4733 ContextIsFound = true;4734 } else {4735 IdentifierInfo *ParamName = &Context.Idents.get(I->first);4736 auto *Param =4737 ImplicitParamDecl::Create(Context, DC, Loc, ParamName, I->second,4738 ImplicitParamKind::CapturedContext);4739 DC->addDecl(Param);4740 CD->setParam(ParamNum, Param);4741 }4742 }4743 assert(ContextIsFound && "no null type for '__context' parameter");4744 if (!ContextIsFound) {4745 // Add __context implicitly if it is not specified.4746 IdentifierInfo *ParamName = &Context.Idents.get("__context");4747 CanQualType ParamType =4748 Context.getPointerType(Context.getCanonicalTagType(RD));4749 auto *Param =4750 ImplicitParamDecl::Create(Context, DC, Loc, ParamName, ParamType,4751 ImplicitParamKind::CapturedContext);4752 DC->addDecl(Param);4753 CD->setContextParam(ParamNum, Param);4754 }4755 // Enter the capturing scope for this captured region.4756 PushCapturedRegionScope(CurScope, CD, RD, Kind, OpenMPCaptureLevel);4757 4758 if (CurScope)4759 PushDeclContext(CurScope, CD);4760 else4761 CurContext = CD;4762 4763 PushExpressionEvaluationContext(4764 ExpressionEvaluationContext::PotentiallyEvaluated);4765}4766 4767void Sema::ActOnCapturedRegionError() {4768 DiscardCleanupsInEvaluationContext();4769 PopExpressionEvaluationContext();4770 PopDeclContext();4771 PoppedFunctionScopePtr ScopeRAII = PopFunctionScopeInfo();4772 CapturedRegionScopeInfo *RSI = cast<CapturedRegionScopeInfo>(ScopeRAII.get());4773 4774 RecordDecl *Record = RSI->TheRecordDecl;4775 Record->setInvalidDecl();4776 4777 SmallVector<Decl*, 4> Fields(Record->fields());4778 ActOnFields(/*Scope=*/nullptr, Record->getLocation(), Record, Fields,4779 SourceLocation(), SourceLocation(), ParsedAttributesView());4780}4781 4782StmtResult Sema::ActOnCapturedRegionEnd(Stmt *S) {4783 // Leave the captured scope before we start creating captures in the4784 // enclosing scope.4785 DiscardCleanupsInEvaluationContext();4786 PopExpressionEvaluationContext();4787 PopDeclContext();4788 PoppedFunctionScopePtr ScopeRAII = PopFunctionScopeInfo();4789 CapturedRegionScopeInfo *RSI = cast<CapturedRegionScopeInfo>(ScopeRAII.get());4790 4791 SmallVector<CapturedStmt::Capture, 4> Captures;4792 SmallVector<Expr *, 4> CaptureInits;4793 if (buildCapturedStmtCaptureList(*this, RSI, Captures, CaptureInits))4794 return StmtError();4795 4796 CapturedDecl *CD = RSI->TheCapturedDecl;4797 RecordDecl *RD = RSI->TheRecordDecl;4798 4799 CapturedStmt *Res = CapturedStmt::Create(4800 getASTContext(), S, static_cast<CapturedRegionKind>(RSI->CapRegionKind),4801 Captures, CaptureInits, CD, RD);4802 4803 CD->setBody(Res->getCapturedStmt());4804 RD->completeDefinition();4805 4806 return Res;4807}4808