Skip to content

Commit e52e53f

Browse files
committed
[Clang] Check for uninitialized use in lambda within CXXOperatorCallExpr
1 parent 1b622a4 commit e52e53f

File tree

2 files changed

+26
-0
lines changed

2 files changed

+26
-0
lines changed

clang/lib/Sema/SemaDecl.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12597,6 +12597,12 @@ namespace {
1259712597
bool isRecordType;
1259812598
bool isPODType;
1259912599
bool isReferenceType;
12600+
// Tracks whether the current expression is being visited within a
12601+
// CXXOperatorCallExpr. This flag is set to true when entering a
12602+
// CXXOperatorCallExpr and reset to false upon exit. It is used to detect
12603+
// when a LambdaExpr is an operand of an operator call, enabling special
12604+
// handling of its capture initializations.
12605+
bool isInCXXOperatorCall;
1260012606

1260112607
bool isInitList;
1260212608
llvm::SmallVector<unsigned, 4> InitFieldIndex;
@@ -12609,6 +12615,7 @@ namespace {
1260912615
isPODType = false;
1261012616
isRecordType = false;
1261112617
isReferenceType = false;
12618+
isInCXXOperatorCall = false;
1261212619
isInitList = false;
1261312620
if (ValueDecl *VD = dyn_cast<ValueDecl>(OrigDecl)) {
1261412621
isPODType = VD->getType().isPODType(S.Context);
@@ -12796,6 +12803,7 @@ namespace {
1279612803
}
1279712804

1279812805
void VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
12806+
isInCXXOperatorCall = true;
1279912807
Expr *Callee = E->getCallee();
1280012808

1280112809
if (isa<UnresolvedLookupExpr>(Callee))
@@ -12804,6 +12812,20 @@ namespace {
1280412812
Visit(Callee);
1280512813
for (auto Arg: E->arguments())
1280612814
HandleValue(Arg->IgnoreParenImpCasts());
12815+
isInCXXOperatorCall = false;
12816+
}
12817+
12818+
void VisitLambdaExpr(LambdaExpr *E) {
12819+
if (isInCXXOperatorCall) {
12820+
for (const auto &init : E->capture_inits()) {
12821+
if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(init))
12822+
HandleDeclRefExpr(DRE);
12823+
else
12824+
Visit(init);
12825+
}
12826+
return;
12827+
}
12828+
Inherited::VisitLambdaExpr(E);
1280712829
}
1280812830

1280912831
void VisitUnaryOperator(UnaryOperator *E) {

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)