[clang] [clang][bytecode] Create temporary before discarding CXXConstructExpr (PR #154280)
Timm Baeder via cfe-commits
cfe-commits at lists.llvm.org
Tue Aug 19 00:53:08 PDT 2025
https://github.com/tbaederr created https://github.com/llvm/llvm-project/pull/154280
Fixes #154110
>From 5add943d38ac3a9b455fa3fcf7992e21138d5cd3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbaeder at redhat.com>
Date: Tue, 19 Aug 2025 09:52:05 +0200
Subject: [PATCH] [clang][bytecode] Create temporary before discarding
CXXConstructExpr
Fixes #154110
---
clang/lib/AST/ByteCode/Compiler.cpp | 14 +++++++-------
clang/test/AST/ByteCode/cxx20.cpp | 16 ++++++++++++++++
clang/test/AST/ByteCode/records.cpp | 16 ++++++++--------
3 files changed, 31 insertions(+), 15 deletions(-)
diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp
index f2ce69a62838e..f7947bd8a3797 100644
--- a/clang/lib/AST/ByteCode/Compiler.cpp
+++ b/clang/lib/AST/ByteCode/Compiler.cpp
@@ -3181,13 +3181,6 @@ bool Compiler<Emitter>::VisitCXXConstructExpr(const CXXConstructExpr *E) {
if (T->isRecordType()) {
const CXXConstructorDecl *Ctor = E->getConstructor();
- // Trivial copy/move constructor. Avoid copy.
- if (Ctor->isDefaulted() && Ctor->isCopyOrMoveConstructor() &&
- Ctor->isTrivial() &&
- E->getArg(0)->isTemporaryObject(Ctx.getASTContext(),
- T->getAsCXXRecordDecl()))
- return this->visitInitializer(E->getArg(0));
-
// If we're discarding a construct expression, we still need
// to allocate a variable and call the constructor and destructor.
if (DiscardResult) {
@@ -3203,6 +3196,13 @@ bool Compiler<Emitter>::VisitCXXConstructExpr(const CXXConstructExpr *E) {
return false;
}
+ // Trivial copy/move constructor. Avoid copy.
+ if (Ctor->isDefaulted() && Ctor->isCopyOrMoveConstructor() &&
+ Ctor->isTrivial() &&
+ E->getArg(0)->isTemporaryObject(Ctx.getASTContext(),
+ T->getAsCXXRecordDecl()))
+ return this->visitInitializer(E->getArg(0));
+
// Zero initialization.
if (E->requiresZeroInitialization()) {
const Record *R = getRecord(E->getType());
diff --git a/clang/test/AST/ByteCode/cxx20.cpp b/clang/test/AST/ByteCode/cxx20.cpp
index cc315d36456d5..67bf9a732d8b7 100644
--- a/clang/test/AST/ByteCode/cxx20.cpp
+++ b/clang/test/AST/ByteCode/cxx20.cpp
@@ -1084,3 +1084,19 @@ namespace Virtual {
static_assert(l.b == 10);
static_assert(l.c == 10);
}
+
+namespace DiscardedTrivialCXXConstructExpr {
+ struct S {
+ constexpr S(int a) : x(a) {}
+ int x;
+ };
+
+ constexpr int foo(int x) { // ref-error {{never produces a constant expression}}
+ throw S(3); // both-note {{not valid in a constant expression}} \
+ // ref-note {{not valid in a constant expression}}
+ return 1;
+ }
+
+ constexpr int y = foo(12); // both-error {{must be initialized by a constant expression}} \
+ // both-note {{in call to}}
+}
diff --git a/clang/test/AST/ByteCode/records.cpp b/clang/test/AST/ByteCode/records.cpp
index 5ca3e2d12e2df..48cf81182c1de 100644
--- a/clang/test/AST/ByteCode/records.cpp
+++ b/clang/test/AST/ByteCode/records.cpp
@@ -1,11 +1,11 @@
-// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -std=c++14 -verify=expected,both %s
-// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -std=c++17 -verify=expected,both %s
-// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -std=c++17 -triple i686 -verify=expected,both %s
-// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -std=c++20 -verify=expected,both %s
-// RUN: %clang_cc1 -verify=ref,both -std=c++14 %s
-// RUN: %clang_cc1 -verify=ref,both -std=c++17 %s
-// RUN: %clang_cc1 -verify=ref,both -std=c++17 -triple i686 %s
-// RUN: %clang_cc1 -verify=ref,both -std=c++20 %s
+// RUN: %clang_cc1 -std=c++14 -verify=expected,both %s -fexperimental-new-constant-interpreter
+// RUN: %clang_cc1 -std=c++17 -verify=expected,both %s -fexperimental-new-constant-interpreter
+// RUN: %clang_cc1 -std=c++17 -verify=expected,both -triple i686 %s -fexperimental-new-constant-interpreter
+// RUN: %clang_cc1 -std=c++20 -verify=expected,both %s -fexperimental-new-constant-interpreter
+// RUN: %clang_cc1 -std=c++14 -verify=ref,both %s
+// RUN: %clang_cc1 -std=c++17 -verify=ref,both %s
+// RUN: %clang_cc1 -std=c++17 -verify=ref,both -triple i686 %s
+// RUN: %clang_cc1 -std=c++20 -verify=ref,both %s
/// Used to crash.
struct Empty {};
More information about the cfe-commits
mailing list