Skip to content

Commit da05208

Browse files
authored
[clang][bytecode] Create temporary before discarding CXXConstructExpr (#154280)
Fixes #154110
1 parent 5753ee2 commit da05208

File tree

3 files changed

+31
-15
lines changed

3 files changed

+31
-15
lines changed

clang/lib/AST/ByteCode/Compiler.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3181,13 +3181,6 @@ bool Compiler<Emitter>::VisitCXXConstructExpr(const CXXConstructExpr *E) {
31813181
if (T->isRecordType()) {
31823182
const CXXConstructorDecl *Ctor = E->getConstructor();
31833183

3184-
// Trivial copy/move constructor. Avoid copy.
3185-
if (Ctor->isDefaulted() && Ctor->isCopyOrMoveConstructor() &&
3186-
Ctor->isTrivial() &&
3187-
E->getArg(0)->isTemporaryObject(Ctx.getASTContext(),
3188-
T->getAsCXXRecordDecl()))
3189-
return this->visitInitializer(E->getArg(0));
3190-
31913184
// If we're discarding a construct expression, we still need
31923185
// to allocate a variable and call the constructor and destructor.
31933186
if (DiscardResult) {
@@ -3203,6 +3196,13 @@ bool Compiler<Emitter>::VisitCXXConstructExpr(const CXXConstructExpr *E) {
32033196
return false;
32043197
}
32053198

3199+
// Trivial copy/move constructor. Avoid copy.
3200+
if (Ctor->isDefaulted() && Ctor->isCopyOrMoveConstructor() &&
3201+
Ctor->isTrivial() &&
3202+
E->getArg(0)->isTemporaryObject(Ctx.getASTContext(),
3203+
T->getAsCXXRecordDecl()))
3204+
return this->visitInitializer(E->getArg(0));
3205+
32063206
// Zero initialization.
32073207
if (E->requiresZeroInitialization()) {
32083208
const Record *R = getRecord(E->getType());

clang/test/AST/ByteCode/cxx20.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1084,3 +1084,19 @@ namespace Virtual {
10841084
static_assert(l.b == 10);
10851085
static_assert(l.c == 10);
10861086
}
1087+
1088+
namespace DiscardedTrivialCXXConstructExpr {
1089+
struct S {
1090+
constexpr S(int a) : x(a) {}
1091+
int x;
1092+
};
1093+
1094+
constexpr int foo(int x) { // ref-error {{never produces a constant expression}}
1095+
throw S(3); // both-note {{not valid in a constant expression}} \
1096+
// ref-note {{not valid in a constant expression}}
1097+
return 1;
1098+
}
1099+
1100+
constexpr int y = foo(12); // both-error {{must be initialized by a constant expression}} \
1101+
// both-note {{in call to}}
1102+
}

clang/test/AST/ByteCode/records.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -std=c++14 -verify=expected,both %s
2-
// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -std=c++17 -verify=expected,both %s
3-
// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -std=c++17 -triple i686 -verify=expected,both %s
4-
// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -std=c++20 -verify=expected,both %s
5-
// RUN: %clang_cc1 -verify=ref,both -std=c++14 %s
6-
// RUN: %clang_cc1 -verify=ref,both -std=c++17 %s
7-
// RUN: %clang_cc1 -verify=ref,both -std=c++17 -triple i686 %s
8-
// RUN: %clang_cc1 -verify=ref,both -std=c++20 %s
1+
// RUN: %clang_cc1 -std=c++14 -verify=expected,both %s -fexperimental-new-constant-interpreter
2+
// RUN: %clang_cc1 -std=c++17 -verify=expected,both %s -fexperimental-new-constant-interpreter
3+
// RUN: %clang_cc1 -std=c++17 -verify=expected,both -triple i686 %s -fexperimental-new-constant-interpreter
4+
// RUN: %clang_cc1 -std=c++20 -verify=expected,both %s -fexperimental-new-constant-interpreter
5+
// RUN: %clang_cc1 -std=c++14 -verify=ref,both %s
6+
// RUN: %clang_cc1 -std=c++17 -verify=ref,both %s
7+
// RUN: %clang_cc1 -std=c++17 -verify=ref,both -triple i686 %s
8+
// RUN: %clang_cc1 -std=c++20 -verify=ref,both %s
99

1010
/// Used to crash.
1111
struct Empty {};

0 commit comments

Comments
 (0)