llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: zhaohui (zhaohuiw42) <details> <summary>Changes</summary> Fix #<!-- -->128058. Track whether a LambdaExpr is an immediate operand of a CXXOperatorCallExpr using a new flag, isInCXXOperatorCall. This enables special handling of capture initializations to detect uninitialized variable uses, such as in `S s = [&]() { return s; }();`. --- Full diff: https://github.com/llvm/llvm-project/pull/129198.diff 2 Files Affected: - (modified) clang/lib/Sema/SemaDecl.cpp (+22) - (modified) clang/test/SemaCXX/uninitialized.cpp (+4) ``````````diff 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 } } `````````` </details> https://github.com/llvm/llvm-project/pull/129198 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits