Skip to content

Commit 54c65ab

Browse files
committed
[Clang] Check for uninitialized use in lambda within CXXOperatorCallExpr
1 parent c298f71 commit 54c65ab

File tree

3 files changed

+22
-0
lines changed

3 files changed

+22
-0
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,7 @@ Bug Fixes to C++ Support
255255
Bug Fixes to AST Handling
256256
^^^^^^^^^^^^^^^^^^^^^^^^^
257257
- Fixed type checking when a statement expression ends in an l-value of atomic type. (#GH106576)
258+
- Fixed uninitialized use check in a lambda within CXXOperatorCallExpr. (#GH129198)
258259

259260
Miscellaneous Bug Fixes
260261
^^^^^^^^^^^^^^^^^^^^^^^

clang/lib/Sema/SemaDecl.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
#include "llvm/ADT/STLForwardCompat.h"
6161
#include "llvm/ADT/SmallString.h"
6262
#include "llvm/ADT/StringExtras.h"
63+
#include "llvm/Support/SaveAndRestore.h"
6364
#include "llvm/TargetParser/Triple.h"
6465
#include <algorithm>
6566
#include <cstring>
@@ -12597,6 +12598,7 @@ namespace {
1259712598
bool isRecordType;
1259812599
bool isPODType;
1259912600
bool isReferenceType;
12601+
bool isInCXXOperatorCall;
1260012602

1260112603
bool isInitList;
1260212604
llvm::SmallVector<unsigned, 4> InitFieldIndex;
@@ -12609,6 +12611,7 @@ namespace {
1260912611
isPODType = false;
1261012612
isRecordType = false;
1261112613
isReferenceType = false;
12614+
isInCXXOperatorCall = false;
1261212615
isInitList = false;
1261312616
if (ValueDecl *VD = dyn_cast<ValueDecl>(OrigDecl)) {
1261412617
isPODType = VD->getType().isPODType(S.Context);
@@ -12796,6 +12799,7 @@ namespace {
1279612799
}
1279712800

1279812801
void VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
12802+
llvm::SaveAndRestore cxxOpCallScope(isInCXXOperatorCall, true);
1279912803
Expr *Callee = E->getCallee();
1280012804

1280112805
if (isa<UnresolvedLookupExpr>(Callee))
@@ -12806,6 +12810,19 @@ namespace {
1280612810
HandleValue(Arg->IgnoreParenImpCasts());
1280712811
}
1280812812

12813+
void VisitLambdaExpr(LambdaExpr *E) {
12814+
if (!isInCXXOperatorCall) {
12815+
Inherited::VisitLambdaExpr(E);
12816+
return;
12817+
}
12818+
12819+
for (const auto &init : E->capture_inits())
12820+
if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(init))
12821+
HandleDeclRefExpr(DRE);
12822+
else
12823+
Visit(init);
12824+
}
12825+
1280912826
void VisitUnaryOperator(UnaryOperator *E) {
1281012827
// For POD record types, addresses of its own members are well-defined.
1281112828
if (E->getOpcode() == UO_AddrOf && isRecordType &&

clang/test/SemaCXX/uninitialized.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -892,6 +892,10 @@ namespace lambdas {
892892
return a1.x;
893893
});
894894
A a2([&] { return a2.x; }); // ok
895+
A a3([=]{ return a3.x; }()); // expected-warning{{variable 'a3' is uninitialized when used within its own initialization}}
896+
A a4([&]{ return a4.x; }()); // expected-warning{{variable 'a4' is uninitialized when used within its own initialization}}
897+
A a5([&]{ return a5; }()); // expected-warning{{variable 'a5' is uninitialized when used within its own initialization}}
898+
A a6([&]{ return a5.x; }()); // ok
895899
}
896900
}
897901

0 commit comments

Comments
 (0)