[clang] [clang] Prevent recursive copy initialization during variadic argument promotion (PR #196744)

via cfe-commits cfe-commits at lists.llvm.org
Sat May 9 11:40:09 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Vineet Agarwal (PlutoDog95)

<details>
<summary>Changes</summary>

Summary

Avoid infinite recursion during variadic argument promotion of volatile
class types.

Clang could previously recurse indefinitely while attempting copy
initialization for variadic constructor arguments involving volatile
class objects, eventually crashing with stack exhaustion.

The recursion occurred when DefaultArgumentPromotion attempted to
materialize a temporary through PerformCopyInitialization, which
re-entered variadic argument promotion for the same type.

This patch prevents the recursive initialization path for volatile
qualified class types and adds a regression test covering the crash.


---
Full diff: https://github.com/llvm/llvm-project/pull/196744.diff


2 Files Affected:

- (modified) clang/lib/Sema/SemaExpr.cpp (+3-1) 
- (added) clang/test/SemaCXX/volatile-vararg-recursion.cpp (+15) 


``````````diff
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 98062afae4577..19f0b961a6fe7 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -935,7 +935,9 @@ ExprResult Sema::DefaultArgumentPromotion(Expr *E) {
   //     is a prvalue for the temporary.
   // FIXME: add some way to gate this entire thing for correctness in
   // potentially potentially evaluated contexts.
-  if (getLangOpts().CPlusPlus && E->isGLValue() && !isUnevaluatedContext()) {
+  if (getLangOpts().CPlusPlus && E->isGLValue() &&
+      !isUnevaluatedContext() &&
+      !E->getType().isVolatileQualified()) {
     ExprResult Temp = PerformCopyInitialization(
                        InitializedEntity::InitializeTemporary(E->getType()),
                                                 E->getExprLoc(), E);
diff --git a/clang/test/SemaCXX/volatile-vararg-recursion.cpp b/clang/test/SemaCXX/volatile-vararg-recursion.cpp
new file mode 100644
index 0000000000000..cf3490baccdd4
--- /dev/null
+++ b/clang/test/SemaCXX/volatile-vararg-recursion.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+namespace cwg535 {
+class X {
+  X(const X &);
+};
+
+struct B {
+  X y;
+  B(...);
+};
+
+extern volatile B b1;
+B b2(b1); // expected-error {{cannot pass object of non-trivial type 'volatile B' through variadic constructor; call will abort at runtime}}
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/196744


More information about the cfe-commits mailing list