summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaExpr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Sema/SemaExpr.cpp')
-rw-r--r--clang/lib/Sema/SemaExpr.cpp41
1 files changed, 30 insertions, 11 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 6a530c71ec2..d9278863534 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -11681,13 +11681,10 @@ static bool isVariableCapturable(CapturingScopeInfo *CSI, VarDecl *Var,
return false;
}
- // Prohibit variably-modified types; they're difficult to deal with.
- if (Var->getType()->isVariablyModifiedType() && (IsBlock || IsLambda)) {
+ // Prohibit variably-modified types in blocks; they're difficult to deal with.
+ if (Var->getType()->isVariablyModifiedType() && IsBlock) {
if (Diagnose) {
- if (IsBlock)
- S.Diag(Loc, diag::err_ref_vm_type);
- else
- S.Diag(Loc, diag::err_lambda_capture_vm_type) << Var->getDeclName();
+ S.Diag(Loc, diag::err_ref_vm_type);
S.Diag(Var->getLocation(), diag::note_previous_decl)
<< Var->getDeclName();
}
@@ -12091,7 +12088,6 @@ static bool captureInLambda(LambdaScopeInfo *LSI,
return true;
}
-
bool Sema::tryCaptureVariable(VarDecl *Var, SourceLocation ExprLoc,
TryCaptureKind Kind, SourceLocation EllipsisLoc,
bool BuildAndDiagnose,
@@ -12228,14 +12224,37 @@ bool Sema::tryCaptureVariable(VarDecl *Var, SourceLocation ExprLoc,
break;
case Type::VariableArray: {
// Losing element qualification here is fine.
- const VariableArrayType *Vat = cast<VariableArrayType>(Ty);
+ const VariableArrayType *VAT = cast<VariableArrayType>(Ty);
// Unknown size indication requires no size computation.
// Otherwise, evaluate and record it.
- if (Expr *Size = Vat->getSizeExpr()) {
- MarkDeclarationsReferencedInExpr(Size);
+ if (auto Size = VAT->getSizeExpr()) {
+ if (auto LSI = dyn_cast<LambdaScopeInfo>(CSI)) {
+ if (!LSI->isVLATypeCaptured(VAT)) {
+ auto ExprLoc = Size->getExprLoc();
+ auto SizeType = Context.getSizeType();
+ auto Lambda = LSI->Lambda;
+
+ // Build the non-static data member.
+ auto Field = FieldDecl::Create(
+ Context, Lambda, ExprLoc, ExprLoc,
+ /*Id*/ nullptr, SizeType, /*TInfo*/ nullptr,
+ /*BW*/ nullptr, /*Mutable*/ false,
+ /*InitStyle*/ ICIS_NoInit);
+ Field->setImplicit(true);
+ Field->setAccess(AS_private);
+ Field->setCapturedVLAType(VAT);
+ Lambda->addDecl(Field);
+
+ LSI->addVLATypeCapture(ExprLoc, SizeType);
+ }
+ } else {
+ // Immediately mark all referenced vars for CapturedStatements,
+ // they all are captured by reference.
+ MarkDeclarationsReferencedInExpr(Size);
+ }
}
- QTy = Vat->getElementType();
+ QTy = VAT->getElementType();
break;
}
case Type::FunctionProto:
OpenPOWER on IntegriCloud