|
27 | 27 | #include "clang/Sema/Template.h" |
28 | 28 | #include "llvm/ADT/STLExtras.h" |
29 | 29 | #include "clang/Lex/Lexer.h" |
| 30 | +#include "clang/AST/Type.h" |
| 31 | + |
30 | 32 | #include <optional> |
31 | 33 | using namespace clang; |
32 | 34 | using namespace sema; |
@@ -1196,14 +1198,66 @@ void Sema::ActOnLambdaExpressionAfterIntroducer(LambdaIntroducer &Intro, |
1196 | 1198 | // for e.g., [n{0}] { }; <-- if no <initializer_list> is included. |
1197 | 1199 | // FIXME: we should create the init capture variable and mark it invalid |
1198 | 1200 | // in this case. |
1199 | | - if (C->InitCaptureType.get().isNull() ) { |
1200 | | - Diag(C->Loc, diag::err_invalid_lambda_capture_initializer_type); // |
1201 | | - continue; // |
| 1201 | +// Ensure the initialization is valid before proceeding |
| 1202 | + |
| 1203 | + |
| 1204 | +if (!C->InitCaptureType || C->InitCaptureType.get().isNull()) { |
| 1205 | + if (!C->Init.isUsable()) { |
| 1206 | + Diag(C->Loc, diag::err_invalid_lambda_capture_initializer_type); |
| 1207 | + continue; |
| 1208 | + } |
| 1209 | + |
| 1210 | + if (!C->Init.get()) { |
| 1211 | + continue; |
| 1212 | + } |
| 1213 | + |
| 1214 | + ASTContext &Ctx = this->Context; |
| 1215 | + QualType DeducedType = C->Init.get()->getType(); |
| 1216 | + |
| 1217 | + if (DeducedType.isNull()) { |
| 1218 | + continue; |
| 1219 | + } |
| 1220 | + |
| 1221 | + if (DeducedType->isVoidType()) { |
| 1222 | + if (!DeducedType->isDependentType()) { |
| 1223 | + C->InitCaptureType = ParsedType::make(Ctx.DependentTy); |
| 1224 | + } else { |
| 1225 | + Diag(C->Loc, diag::err_invalid_lambda_capture_initializer_type); |
| 1226 | + } |
| 1227 | + continue; |
| 1228 | + } |
| 1229 | + |
| 1230 | + if (isa<InitListExpr>(C->Init.get())) { |
| 1231 | + IdentifierInfo *DummyID = &Ctx.Idents.get("lambda_tmp_var"); |
| 1232 | + QualType DummyType = Ctx.UnknownAnyTy; |
| 1233 | + |
| 1234 | + auto *TempVarDecl = VarDecl::Create( |
| 1235 | + Ctx, nullptr, C->Loc, C->Loc, |
| 1236 | + DummyID, DummyType, nullptr, SC_None |
| 1237 | + ); |
| 1238 | + |
| 1239 | + if (!TempVarDecl) { |
| 1240 | + continue; |
1202 | 1241 | } |
1203 | 1242 |
|
1204 | | - if (C->Init.get()->containsUnexpandedParameterPack() && |
1205 | | - !C->InitCaptureType.get()->getAs<PackExpansionType>()) |
1206 | | - DiagnoseUnexpandedParameterPack(C->Init.get(), UPPC_Initializer); |
| 1243 | + DeducedType = deduceVarTypeFromInitializer( |
| 1244 | + TempVarDecl, TempVarDecl->getDeclName(), |
| 1245 | + TempVarDecl->getType(), nullptr, |
| 1246 | + TempVarDecl->getSourceRange(), |
| 1247 | + false, C->Init.get() |
| 1248 | + ); |
| 1249 | + |
| 1250 | + if (DeducedType.isNull()) { |
| 1251 | + Diag(C->Loc, diag::err_invalid_lambda_capture_initializer_type); |
| 1252 | + C->InitCaptureType = ParsedType::make(Ctx.DependentTy); |
| 1253 | + continue; |
| 1254 | + } |
| 1255 | + } |
| 1256 | + |
| 1257 | + if (!DeducedType.isNull()) { |
| 1258 | + C->InitCaptureType = ParsedType::make(DeducedType); |
| 1259 | + } |
| 1260 | +} |
1207 | 1261 |
|
1208 | 1262 | unsigned InitStyle; |
1209 | 1263 | switch (C->InitKind) { |
|
0 commit comments