[clang] [clang][bytecode] Avoid copies with elidable CXXConstructExprs (PR #166931)
Timm Baeder via cfe-commits
cfe-commits at lists.llvm.org
Fri Nov 7 04:15:50 PST 2025
https://github.com/tbaederr updated https://github.com/llvm/llvm-project/pull/166931
>From b61b4158539d90e83686c5b84c4b972cd235e162 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbaeder at redhat.com>
Date: Fri, 7 Nov 2025 13:01:49 +0100
Subject: [PATCH] [clang][bytecode] Avoid copies with elidable
CXXConstructExprs
To fix the newly added cwg6.cpp.
---
clang/lib/AST/ByteCode/Compiler.cpp | 13 ++++++++++++-
clang/test/AST/ByteCode/cxx11.cpp | 8 ++++++++
2 files changed, 20 insertions(+), 1 deletion(-)
diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp
index 84f7e6287609c..0a87d3c9bea1a 100644
--- a/clang/lib/AST/ByteCode/Compiler.cpp
+++ b/clang/lib/AST/ByteCode/Compiler.cpp
@@ -3235,7 +3235,8 @@ bool Compiler<Emitter>::VisitCXXConstructExpr(const CXXConstructExpr *E) {
return this->visitInitializer(E->getArg(0));
// Zero initialization.
- if (E->requiresZeroInitialization()) {
+ bool ZeroInit = E->requiresZeroInitialization();
+ if (ZeroInit) {
const Record *R = getRecord(E->getType());
if (!this->visitZeroRecordInitializer(R, E))
@@ -3246,6 +3247,16 @@ bool Compiler<Emitter>::VisitCXXConstructExpr(const CXXConstructExpr *E) {
return true;
}
+ // Avoid materializing a temporary for an elidable copy/move constructor.
+ if (!ZeroInit && E->isElidable()) {
+ const Expr *SrcObj = E->getArg(0);
+ assert(SrcObj->isTemporaryObject(Ctx.getASTContext(), Ctor->getParent()));
+ assert(Ctx.getASTContext().hasSameUnqualifiedType(E->getType(),
+ SrcObj->getType()));
+ if (const auto *ME = dyn_cast<MaterializeTemporaryExpr>(SrcObj))
+ return this->visitInitializer(ME->getSubExpr());
+ }
+
const Function *Func = getFunction(Ctor);
if (!Func)
diff --git a/clang/test/AST/ByteCode/cxx11.cpp b/clang/test/AST/ByteCode/cxx11.cpp
index e283a7b42e554..753e51dfbfc1c 100644
--- a/clang/test/AST/ByteCode/cxx11.cpp
+++ b/clang/test/AST/ByteCode/cxx11.cpp
@@ -379,3 +379,11 @@ namespace DiscardedAddrLabel {
}
}
+struct Counter {
+ int copies;
+ constexpr Counter(int copies) : copies(copies) {}
+ constexpr Counter(const Counter& other) : copies(other.copies + 1) {}
+};
+// Passing an lvalue by value makes a non-elidable copy.
+constexpr int PassByValue(Counter c) { return c.copies; }
+static_assert(PassByValue(Counter(0)) == 0, "expect no copies");
More information about the cfe-commits
mailing list