Author: zhaohui Date: 2025-03-07T16:01:23+08:00 New Revision: 3a67c7c6f7f6d41adf4487d099c1225c31caf8c3
URL: https://github.com/llvm/llvm-project/commit/3a67c7c6f7f6d41adf4487d099c1225c31caf8c3 DIFF: https://github.com/llvm/llvm-project/commit/3a67c7c6f7f6d41adf4487d099c1225c31caf8c3.diff LOG: [Clang] Check for uninitialized use in lambda within CXXOperatorCallExpr (#129198) 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; }();`. Fix #128058 Added: Modified: clang/docs/ReleaseNotes.rst clang/lib/Sema/SemaDecl.cpp clang/test/SemaCXX/uninitialized.cpp Removed: ################################################################################ diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index e42541818a0e9..28856c27317f3 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -299,6 +299,7 @@ Improvements to C++ diagnostics Bug Fixes to AST Handling ^^^^^^^^^^^^^^^^^^^^^^^^^ - Fixed type checking when a statement expression ends in an l-value of atomic type. (#GH106576) +- Fixed uninitialized use check in a lambda within CXXOperatorCallExpr. (#GH129198) Miscellaneous Bug Fixes ^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 8c5125b8eb6d9..714210c3856d7 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -61,6 +61,7 @@ #include "llvm/ADT/STLForwardCompat.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringExtras.h" +#include "llvm/Support/SaveAndRestore.h" #include "llvm/TargetParser/Triple.h" #include <algorithm> #include <cstring> @@ -12611,6 +12612,7 @@ namespace { bool isRecordType; bool isPODType; bool isReferenceType; + bool isInCXXOperatorCall; bool isInitList; llvm::SmallVector<unsigned, 4> InitFieldIndex; @@ -12623,6 +12625,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); @@ -12810,6 +12813,7 @@ namespace { } void VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) { + llvm::SaveAndRestore CxxOpCallScope(isInCXXOperatorCall, true); Expr *Callee = E->getCallee(); if (isa<UnresolvedLookupExpr>(Callee)) @@ -12820,6 +12824,19 @@ namespace { HandleValue(Arg->IgnoreParenImpCasts()); } + void VisitLambdaExpr(LambdaExpr *E) { + if (!isInCXXOperatorCall) { + Inherited::VisitLambdaExpr(E); + return; + } + + for (Expr *Init : E->capture_inits()) + if (DeclRefExpr *DRE = dyn_cast_if_present<DeclRefExpr>(Init)) + HandleDeclRefExpr(DRE); + else if (Init) + Visit(Init); + } + void VisitUnaryOperator(UnaryOperator *E) { // For POD record types, addresses of its own members are well-defined. if (E->getOpcode() == UO_AddrOf && isRecordType && diff --git a/clang/test/SemaCXX/uninitialized.cpp b/clang/test/SemaCXX/uninitialized.cpp index 4af2c998f082e..c7b987e2172e6 100644 --- a/clang/test/SemaCXX/uninitialized.cpp +++ b/clang/test/SemaCXX/uninitialized.cpp @@ -892,6 +892,11 @@ 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 + A a7 = [&a7] { return a7; }(); // expected-warning{{variable 'a7' is uninitialized when used within its own initialization}} } } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits