[clang] 52fbf34 - [Clang] Fix stack-use-after-return in TryArrayCopy by allocating OpaqueValueExpr on the ASTContext (#192080)
via cfe-commits
cfe-commits at lists.llvm.org
Fri May 8 07:23:00 PDT 2026
Author: TPPPP
Date: 2026-05-08T14:22:55Z
New Revision: 52fbf34e35194d05951dfd76a45cc886cf3e4ba5
URL: https://github.com/llvm/llvm-project/commit/52fbf34e35194d05951dfd76a45cc886cf3e4ba5
DIFF: https://github.com/llvm/llvm-project/commit/52fbf34e35194d05951dfd76a45cc886cf3e4ba5.diff
LOG: [Clang] Fix stack-use-after-return in TryArrayCopy by allocating OpaqueValueExpr on the ASTContext (#192080)
Change the `OpaqueValueExpr` in `TryArrayCopy` from stack memory to heap
memory to avoid stack-use-after-return.
Fixes #192026
Added:
clang/test/SemaCXX/gh192026.cpp
Modified:
clang/docs/ReleaseNotes.rst
clang/lib/Sema/SemaInit.cpp
Removed:
################################################################################
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 700fbe4304141..2a7c315192f2d 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -539,6 +539,8 @@ Bug Fixes in This Version
- Clang now emits an error for friend declarations of lambda members. (#GH26540)
- Fixed a crash caused by lambda capture handling in delayed default arguments. (#GH176534)
- Fixed a crash when parsing invalid ``static_assert`` declarations with string-literal messages (#GH187690).
+- Fixed a potential stack-use-after-return issue in Clang when copy-initializing
+ an array via an element-at-a-time copy loop (#GH192026)
Bug Fixes to Compiler Builtins
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index 92fc73814deb8..ceac3722376fa 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -4380,10 +4380,13 @@ static void TryArrayCopy(Sema &S, const InitializationKind &Kind,
InitializedEntity::InitializeElement(S.Context, 0, Entity);
QualType InitEltT =
S.Context.getAsArrayType(Initializer->getType())->getElementType();
- OpaqueValueExpr OVE(Initializer->getExprLoc(), InitEltT,
- Initializer->getValueKind(),
- Initializer->getObjectKind());
- Expr *OVEAsExpr = &OVE;
+
+ // FIXME: Here's a functional memory leak cuz we don't have a temporary
+ // allocator at the moment
+ OpaqueValueExpr *OVE = new (S.Context) OpaqueValueExpr(
+ Initializer->getExprLoc(), InitEltT, Initializer->getValueKind(),
+ Initializer->getObjectKind());
+ Expr *OVEAsExpr = OVE;
Sequence.InitializeFrom(S, Element, Kind, OVEAsExpr,
/*TopLevelOfInitList*/ false,
TreatUnavailableAsInvalid);
diff --git a/clang/test/SemaCXX/gh192026.cpp b/clang/test/SemaCXX/gh192026.cpp
new file mode 100644
index 0000000000000..3b179f8420119
--- /dev/null
+++ b/clang/test/SemaCXX/gh192026.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct ControlSwitcher { bool b; };
+
+class ComplexChain {
+ volatile union {
+ char flag_byte;
+ int ref_count;
+ } state_flags[5]; // expected-note {{copy constructor of 'ComplexChain' is implicitly deleted because field 'state_flags' has no copy constructor}}
+
+ ControlSwitcher cs{true};
+
+ ComplexChain trigger_bug() {
+ return *this; // expected-error {{call to implicitly-deleted copy constructor of 'ComplexChain'}}
+ }
+};
More information about the cfe-commits
mailing list