diff options
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r-- | clang/lib/Sema/Sema.cpp | 4 | ||||
-rw-r--r-- | clang/lib/Sema/SemaStmt.cpp | 4 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplateVariadic.cpp | 14 |
3 files changed, 16 insertions, 6 deletions
diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp index e07f60989d8..45fd2d3249d 100644 --- a/clang/lib/Sema/Sema.cpp +++ b/clang/lib/Sema/Sema.cpp @@ -1393,8 +1393,8 @@ void Sema::PopFunctionScopeInfo(const AnalysisBasedWarnings::Policy *WP, delete Scope; } -void Sema::PushCompoundScope() { - getCurFunction()->CompoundScopes.push_back(CompoundScopeInfo()); +void Sema::PushCompoundScope(bool IsStmtExpr) { + getCurFunction()->CompoundScopes.push_back(CompoundScopeInfo(IsStmtExpr)); } void Sema::PopCompoundScope() { diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index 1ebc36716a8..93907038e05 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -337,8 +337,8 @@ void Sema::DiagnoseUnusedExprResult(const Stmt *S) { DiagRuntimeBehavior(Loc, nullptr, PDiag(DiagID) << R1 << R2); } -void Sema::ActOnStartOfCompoundStmt() { - PushCompoundScope(); +void Sema::ActOnStartOfCompoundStmt(bool IsStmtExpr) { + PushCompoundScope(IsStmtExpr); } void Sema::ActOnFinishOfCompoundStmt() { diff --git a/clang/lib/Sema/SemaTemplateVariadic.cpp b/clang/lib/Sema/SemaTemplateVariadic.cpp index d81837dad50..7aa0e317df0 100644 --- a/clang/lib/Sema/SemaTemplateVariadic.cpp +++ b/clang/lib/Sema/SemaTemplateVariadic.cpp @@ -314,8 +314,18 @@ Sema::DiagnoseUnexpandedParameterPacks(SourceLocation Loc, // later. SmallVector<UnexpandedParameterPack, 4> LambdaParamPackReferences; for (unsigned N = FunctionScopes.size(); N; --N) { - if (sema::LambdaScopeInfo *LSI = - dyn_cast<sema::LambdaScopeInfo>(FunctionScopes[N-1])) { + sema::FunctionScopeInfo *Func = FunctionScopes[N-1]; + // We do not permit pack expansion that would duplicate a statement + // expression, not even within a lambda. + // FIXME: We could probably support this for statement expressions that do + // not contain labels, and for pack expansions that expand both the stmt + // expr and the enclosing lambda. + if (std::any_of( + Func->CompoundScopes.begin(), Func->CompoundScopes.end(), + [](sema::CompoundScopeInfo &CSI) { return CSI.IsStmtExpr; })) + break; + + if (auto *LSI = dyn_cast<sema::LambdaScopeInfo>(Func)) { if (N == FunctionScopes.size()) { for (auto &Param : Unexpanded) { auto *PD = dyn_cast_or_null<ParmVarDecl>( |