This revision was landed with ongoing or failed builds. This revision was automatically updated to reflect the committed changes. Closed by commit rGedbea62f72f7: [clang] Correctly handle by-reference capture with an initializer that is a… (authored by massberg).
Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D139125/new/ https://reviews.llvm.org/D139125 Files: clang/include/clang/Sema/Sema.h clang/lib/Sema/SemaLambda.cpp clang/lib/Sema/TreeTransform.h clang/test/SemaCXX/lambda-pack-expansion.cpp clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp
Index: clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp =================================================================== --- clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp +++ clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp @@ -2306,6 +2306,30 @@ hasName("cc"), hasInitializer(integerLiteral(equals(1)))))))))); } +TEST_P(ASTMatchersTest, LambdaCaptureTest_BindsToCaptureOfReferenceType) { + if (!GetParam().isCXX20OrLater()) { + return; + } + auto matcher = lambdaExpr(hasAnyCapture( + lambdaCapture(capturesVar(varDecl(hasType(referenceType())))))); + EXPECT_TRUE(matches("template <class ...T> void f(T &...args) {" + " [&...args = args] () mutable {" + " }();" + "}" + "int main() {" + " int a;" + " f(a);" + "}", matcher)); + EXPECT_FALSE(matches("template <class ...T> void f(T &...args) {" + " [...args = args] () mutable {" + " }();" + "}" + "int main() {" + " int a;" + " f(a);" + "}", matcher)); +} + TEST(ASTMatchersTestObjC, ObjCMessageCalees) { StatementMatcher MessagingFoo = objcMessageExpr(callee(objcMethodDecl(hasName("foo")))); Index: clang/test/SemaCXX/lambda-pack-expansion.cpp =================================================================== --- /dev/null +++ clang/test/SemaCXX/lambda-pack-expansion.cpp @@ -0,0 +1,22 @@ +// RUN: %clang_cc1 -std=c++20 -Wno-unused-value -fsyntax-only -verify %s + +namespace GH49266 { +struct X { + X() = default; + X(X const&) = delete; // expected-note {{'X' has been explicitly marked deleted here}} +}; + +void take_by_copy(auto &...args) { + [...args = args] {}(); // expected-error {{call to deleted constructor}} +} + +void take_by_ref(auto &...args) { + [&...args = args] {}(); // args is passed by reference and not copied. +} + +void foo() { + X x; + take_by_copy(x); // expected-note {{in instantiation of function template specialization}} + take_by_ref(x); +} +} Index: clang/lib/Sema/TreeTransform.h =================================================================== --- clang/lib/Sema/TreeTransform.h +++ clang/lib/Sema/TreeTransform.h @@ -13149,7 +13149,7 @@ QualType NewInitCaptureType = getSema().buildLambdaInitCaptureInitialization( - C->getLocation(), OldVD->getType()->isReferenceType(), + C->getLocation(), C->getCaptureKind() == LCK_ByRef, EllipsisLoc, NumExpansions, OldVD->getIdentifier(), cast<VarDecl>(C->getCapturedVar())->getInitStyle() != VarDecl::CInit, @@ -13331,7 +13331,7 @@ break; } NewVDs.push_back(NewVD); - getSema().addInitCapture(LSI, NewVD); + getSema().addInitCapture(LSI, NewVD, C->getCaptureKind() == LCK_ByRef); } if (Invalid) Index: clang/lib/Sema/SemaLambda.cpp =================================================================== --- clang/lib/Sema/SemaLambda.cpp +++ clang/lib/Sema/SemaLambda.cpp @@ -887,11 +887,12 @@ return NewVD; } -void Sema::addInitCapture(LambdaScopeInfo *LSI, VarDecl *Var) { +void Sema::addInitCapture(LambdaScopeInfo *LSI, VarDecl *Var, + bool isReferenceType) { assert(Var->isInitCapture() && "init capture flag should be set"); - LSI->addCapture(Var, /*isBlock*/false, Var->getType()->isReferenceType(), - /*isNested*/false, Var->getLocation(), SourceLocation(), - Var->getType(), /*Invalid*/false); + LSI->addCapture(Var, /*isBlock*/ false, isReferenceType, + /*isNested*/ false, Var->getLocation(), SourceLocation(), + Var->getType(), /*Invalid*/ false); } void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro, @@ -1261,7 +1262,7 @@ } if (C->Init.isUsable()) { - addInitCapture(LSI, cast<VarDecl>(Var)); + addInitCapture(LSI, cast<VarDecl>(Var), C->Kind == LCK_ByRef); } else { TryCaptureKind Kind = C->Kind == LCK_ByRef ? TryCapture_ExplicitByRef : TryCapture_ExplicitByVal; Index: clang/include/clang/Sema/Sema.h =================================================================== --- clang/include/clang/Sema/Sema.h +++ clang/include/clang/Sema/Sema.h @@ -7097,7 +7097,8 @@ unsigned InitStyle, Expr *Init); /// Add an init-capture to a lambda scope. - void addInitCapture(sema::LambdaScopeInfo *LSI, VarDecl *Var); + void addInitCapture(sema::LambdaScopeInfo *LSI, VarDecl *Var, + bool isReferenceType); /// Note that we have finished the explicit captures for the /// given lambda.
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits