https://github.com/zhaohuiw42 updated https://github.com/llvm/llvm-project/pull/129198
>From e52e53f5756172f02b8075f0480ee12f4eef9add Mon Sep 17 00:00:00 2001 From: zhaohui <zhaohui...@gmail.com> Date: Fri, 28 Feb 2025 14:12:39 +0800 Subject: [PATCH] [Clang] Check for uninitialized use in lambda within CXXOperatorCallExpr --- clang/lib/Sema/SemaDecl.cpp | 22 ++++++++++++++++++++++ clang/test/SemaCXX/uninitialized.cpp | 4 ++++ 2 files changed, 26 insertions(+) diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 285bd27a35a76..ad93b4a858543 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -12597,6 +12597,12 @@ namespace { bool isRecordType; bool isPODType; bool isReferenceType; + // Tracks whether the current expression is being visited within a + // CXXOperatorCallExpr. This flag is set to true when entering a + // CXXOperatorCallExpr and reset to false upon exit. It is used to detect + // when a LambdaExpr is an operand of an operator call, enabling special + // handling of its capture initializations. + bool isInCXXOperatorCall; bool isInitList; llvm::SmallVector<unsigned, 4> InitFieldIndex; @@ -12609,6 +12615,7 @@ namespace { isPODType = false; isRecordType = false; isReferenceType = false; + isInCXXOperatorCall = false; isInitList = false; if (ValueDecl *VD = dyn_cast<ValueDecl>(OrigDecl)) { isPODType = VD->getType().isPODType(S.Context); @@ -12796,6 +12803,7 @@ namespace { } void VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) { + isInCXXOperatorCall = true; Expr *Callee = E->getCallee(); if (isa<UnresolvedLookupExpr>(Callee)) @@ -12804,6 +12812,20 @@ namespace { Visit(Callee); for (auto Arg: E->arguments()) HandleValue(Arg->IgnoreParenImpCasts()); + isInCXXOperatorCall = false; + } + + void VisitLambdaExpr(LambdaExpr *E) { + if (isInCXXOperatorCall) { + for (const auto &init : E->capture_inits()) { + if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(init)) + HandleDeclRefExpr(DRE); + else + Visit(init); + } + return; + } + Inherited::VisitLambdaExpr(E); } void VisitUnaryOperator(UnaryOperator *E) { diff --git a/clang/test/SemaCXX/uninitialized.cpp b/clang/test/SemaCXX/uninitialized.cpp index 4af2c998f082e..654d955b3cc72 100644 --- a/clang/test/SemaCXX/uninitialized.cpp +++ b/clang/test/SemaCXX/uninitialized.cpp @@ -892,6 +892,10 @@ namespace lambdas { return a1.x; }); A a2([&] { return a2.x; }); // ok + A a3([=]{ return a3.x; }()); // expected-warning{{variable 'a3' is uninitialized when used within its own initialization}} + A a4([&]{ return a4.x; }()); // expected-warning{{variable 'a4' is uninitialized when used within its own initialization}} + A a5([&]{ return a5; }()); // expected-warning{{variable 'a5' is uninitialized when used within its own initialization}} + A a6([&]{ return a5.x; }()); // ok } } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits