[clang] [Clang] Check for uninitialized use in lambda within CXXOperatorCallExpr (PR #129198)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Feb 28 21:16:21 PST 2025
https://github.com/zhaohuiw42 updated https://github.com/llvm/llvm-project/pull/129198
>From 6667d8b34a2d33b1e0b2f56466cac558d13cbf80 Mon Sep 17 00:00:00 2001
From: zhaohui <zhaohuiw94 at gmail.com>
Date: Fri, 28 Feb 2025 14:12:39 +0800
Subject: [PATCH] [Clang] Check for uninitialized use in lambda within
CXXOperatorCallExpr
---
clang/docs/ReleaseNotes.rst | 1 +
clang/lib/Sema/SemaDecl.cpp | 17 +++++++++++++++++
clang/test/SemaCXX/uninitialized.cpp | 4 ++++
3 files changed, 22 insertions(+)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 7873c2048e53c..b04eac75440c5 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -255,6 +255,7 @@ Bug Fixes to C++ Support
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 86e65e56accc8..f81908c81a8e5 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -60,6 +60,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>
@@ -12597,6 +12598,7 @@ namespace {
bool isRecordType;
bool isPODType;
bool isReferenceType;
+ bool isInCXXOperatorCall;
bool isInitList;
llvm::SmallVector<unsigned, 4> InitFieldIndex;
@@ -12609,6 +12611,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 +12799,7 @@ namespace {
}
void VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
+ llvm::SaveAndRestore CxxOpCallScope(isInCXXOperatorCall, true);
Expr *Callee = E->getCallee();
if (isa<UnresolvedLookupExpr>(Callee))
@@ -12806,6 +12810,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_or_null<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..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
}
}
More information about the cfe-commits
mailing list