@@ -6037,6 +6037,12 @@ static EvalStmtResult EvaluateStmt(StmtResult &Result, EvalInfo &Info,
60376037 const VarDecl *VD = dyn_cast_or_null<VarDecl>(D);
60386038 if (VD && !CheckLocalVariableDeclaration(Info, VD))
60396039 return ESR_Failed;
6040+
6041+ if (const auto *ESD = dyn_cast<CXXExpansionStmtDecl>(D)) {
6042+ assert(ESD->getInstantiations() && "not expanded?");
6043+ return EvaluateStmt(Result, Info, ESD->getInstantiations(), Case);
6044+ }
6045+
60406046 // Each declaration initialization is its own full-expression.
60416047 FullExpressionRAII Scope(Info);
60426048 if (!EvaluateDecl(Info, D, /*EvaluateConditionDecl=*/true) &&
@@ -6309,6 +6315,40 @@ static EvalStmtResult EvaluateStmt(StmtResult &Result, EvalInfo &Info,
63096315 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
63106316 }
63116317
6318+ case Stmt::CXXExpansionStmtInstantiationClass: {
6319+ BlockScopeRAII Scope(Info);
6320+ const auto *Expansion = cast<CXXExpansionStmtInstantiation>(S);
6321+ for (const Stmt *Shared : Expansion->getSharedStmts()) {
6322+ EvalStmtResult ESR = EvaluateStmt(Result, Info, Shared);
6323+ if (ESR != ESR_Succeeded) {
6324+ if (ESR != ESR_Failed && !Scope.destroy())
6325+ return ESR_Failed;
6326+ return ESR;
6327+ }
6328+ }
6329+
6330+ // No need to push an extra scope for these since they're already
6331+ // CompoundStmts.
6332+ EvalStmtResult ESR = ESR_Succeeded;
6333+ for (const Stmt *Instantiation : Expansion->getInstantiations()) {
6334+ ESR = EvaluateStmt(Result, Info, Instantiation);
6335+ if (ESR == ESR_Failed ||
6336+ ShouldPropagateBreakContinue(Info, Expansion, &Scope, ESR))
6337+ return ESR;
6338+ if (ESR != ESR_Continue) {
6339+ // Succeeded here actually means we encountered a 'break'.
6340+ assert(ESR == ESR_Succeeded || ESR == ESR_Returned);
6341+ break;
6342+ }
6343+ }
6344+
6345+ // Map Continue back to Succeeded if we fell off the end of the loop.
6346+ if (ESR == ESR_Continue)
6347+ ESR = ESR_Succeeded;
6348+
6349+ return Scope.destroy() ? ESR : ESR_Failed;
6350+ }
6351+
63126352 case Stmt::SwitchStmtClass:
63136353 return EvaluateSwitch(Result, Info, cast<SwitchStmt>(S));
63146354
0 commit comments