[clang] 92ac46e - [clang][Interp] Handle CXXParenListInitExprs
Timm Bäder via cfe-commits
cfe-commits at lists.llvm.org
Wed Sep 6 06:27:09 PDT 2023
Author: Timm Bäder
Date: 2023-09-06T15:26:54+02:00
New Revision: 92ac46e703cfa0a5313f83d5c5fa3b298edaa777
URL: https://github.com/llvm/llvm-project/commit/92ac46e703cfa0a5313f83d5c5fa3b298edaa777
DIFF: https://github.com/llvm/llvm-project/commit/92ac46e703cfa0a5313f83d5c5fa3b298edaa777.diff
LOG: [clang][Interp] Handle CXXParenListInitExprs
Differential Revision: https://reviews.llvm.org/D156047
Added:
Modified:
clang/lib/AST/Interp/ByteCodeExprGen.cpp
clang/lib/AST/Interp/ByteCodeExprGen.h
clang/test/AST/Interp/records.cpp
clang/test/SemaCXX/source_location.cpp
Removed:
################################################################################
diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index 043a3eb6346e02..77334268df1c14 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -511,6 +511,58 @@ bool ByteCodeExprGen<Emitter>::VisitArraySubscriptExpr(
return this->emitArrayElemPtrPop(IndexT, E);
}
+template <class Emitter>
+bool ByteCodeExprGen<Emitter>::visitInitList(ArrayRef<const Expr *> Inits,
+ const Expr *E) {
+ assert(E->getType()->isRecordType());
+ const Record *R = getRecord(E->getType());
+
+ unsigned InitIndex = 0;
+ for (const Expr *Init : Inits) {
+ if (!this->emitDupPtr(E))
+ return false;
+
+ if (std::optional<PrimType> T = classify(Init)) {
+ const Record::Field *FieldToInit = R->getField(InitIndex);
+ if (!this->visit(Init))
+ return false;
+ if (!this->emitInitField(*T, FieldToInit->Offset, E))
+ return false;
+ if (!this->emitPopPtr(E))
+ return false;
+ ++InitIndex;
+ } else {
+ // Initializer for a direct base class.
+ if (const Record::Base *B = R->getBase(Init->getType())) {
+ if (!this->emitGetPtrBasePop(B->Offset, Init))
+ return false;
+
+ if (!this->visitInitializer(Init))
+ return false;
+
+ if (!this->emitPopPtr(E))
+ return false;
+ // Base initializers don't increase InitIndex, since they don't count
+ // into the Record's fields.
+ } else {
+ const Record::Field *FieldToInit = R->getField(InitIndex);
+ // Non-primitive case. Get a pointer to the field-to-initialize
+ // on the stack and recurse into visitInitializer().
+ if (!this->emitGetPtrField(FieldToInit->Offset, Init))
+ return false;
+
+ if (!this->visitInitializer(Init))
+ return false;
+
+ if (!this->emitPopPtr(E))
+ return false;
+ ++InitIndex;
+ }
+ }
+ }
+ return true;
+}
+
template <class Emitter>
bool ByteCodeExprGen<Emitter>::VisitInitListExpr(const InitListExpr *E) {
// Handle discarding first.
@@ -530,56 +582,8 @@ bool ByteCodeExprGen<Emitter>::VisitInitListExpr(const InitListExpr *E) {
}
QualType T = E->getType();
- if (T->isRecordType()) {
- const Record *R = getRecord(T);
-
- unsigned InitIndex = 0;
- for (const Expr *Init : E->inits()) {
- if (!this->emitDupPtr(E))
- return false;
-
- if (std::optional<PrimType> T = classify(Init)) {
- const Record::Field *FieldToInit = R->getField(InitIndex);
- if (!this->visit(Init))
- return false;
-
- if (!this->emitInitField(*T, FieldToInit->Offset, E))
- return false;
-
- if (!this->emitPopPtr(E))
- return false;
- ++InitIndex;
- } else {
- // Initializer for a direct base class.
- if (const Record::Base *B = R->getBase(Init->getType())) {
- if (!this->emitGetPtrBasePop(B->Offset, Init))
- return false;
-
- if (!this->visitInitializer(Init))
- return false;
-
- if (!this->emitPopPtr(E))
- return false;
- // Base initializers don't increase InitIndex, since they don't count
- // into the Record's fields.
- } else {
- const Record::Field *FieldToInit = R->getField(InitIndex);
- // Non-primitive case. Get a pointer to the field-to-initialize
- // on the stack and recurse into visitInitializer().
- if (!this->emitGetPtrField(FieldToInit->Offset, Init))
- return false;
-
- if (!this->visitInitializer(Init))
- return false;
-
- if (!this->emitPopPtr(E))
- return false;
- ++InitIndex;
- }
- }
- }
- return true;
- }
+ if (T->isRecordType())
+ return this->visitInitList(E->inits(), E);
if (T->isArrayType()) {
// FIXME: Array fillers.
@@ -612,6 +616,21 @@ bool ByteCodeExprGen<Emitter>::VisitInitListExpr(const InitListExpr *E) {
return false;
}
+template <class Emitter>
+bool ByteCodeExprGen<Emitter>::VisitCXXParenListInitExpr(
+ const CXXParenListInitExpr *E) {
+ if (DiscardResult) {
+ for (const Expr *Init : E->getInitExprs()) {
+ if (!this->discard(Init))
+ return false;
+ }
+ return true;
+ }
+
+ assert(E->getType()->isRecordType());
+ return this->visitInitList(E->getInitExprs(), E);
+}
+
template <class Emitter>
bool ByteCodeExprGen<Emitter>::VisitSubstNonTypeTemplateParmExpr(
const SubstNonTypeTemplateParmExpr *E) {
diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.h b/clang/lib/AST/Interp/ByteCodeExprGen.h
index 8ff8bc568b687b..4b5d298fd1b317 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.h
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.h
@@ -80,6 +80,7 @@ class ByteCodeExprGen : public ConstStmtVisitor<ByteCodeExprGen<Emitter>, bool>,
bool VisitSubstNonTypeTemplateParmExpr(const SubstNonTypeTemplateParmExpr *E);
bool VisitArraySubscriptExpr(const ArraySubscriptExpr *E);
bool VisitInitListExpr(const InitListExpr *E);
+ bool VisitCXXParenListInitExpr(const CXXParenListInitExpr *E);
bool VisitConstantExpr(const ConstantExpr *E);
bool VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
bool VisitMemberExpr(const MemberExpr *E);
@@ -199,6 +200,8 @@ class ByteCodeExprGen : public ConstStmtVisitor<ByteCodeExprGen<Emitter>, bool>,
return this->emitPopPtr(I);
}
+ bool visitInitList(ArrayRef<const Expr *> Inits, const Expr *E);
+
/// Creates a local primitive value.
unsigned allocateLocalPrimitive(DeclTy &&Decl, PrimType Ty, bool IsConst,
bool IsExtended = false);
diff --git a/clang/test/AST/Interp/records.cpp b/clang/test/AST/Interp/records.cpp
index 4e39ded41ad25f..bcc84087fc5402 100644
--- a/clang/test/AST/Interp/records.cpp
+++ b/clang/test/AST/Interp/records.cpp
@@ -941,7 +941,7 @@ namespace TemporaryObjectExpr {
static_assert(foo(F()) == 0, "");
}
-namespace ZeroInit {
+ namespace ZeroInit {
struct F {
int a;
};
@@ -1052,3 +1052,17 @@ namespace ZeroInit {
};
#endif
}
+
+#if __cplusplus >= 202002L
+namespace ParenInit {
+ struct A {
+ int a;
+ };
+
+ struct B : A {
+ int b;
+ };
+
+ constexpr B b(A(1),2);
+}
+#endif
diff --git a/clang/test/SemaCXX/source_location.cpp b/clang/test/SemaCXX/source_location.cpp
index 6dca7cd58612aa..e92fb35b653a8f 100644
--- a/clang/test/SemaCXX/source_location.cpp
+++ b/clang/test/SemaCXX/source_location.cpp
@@ -4,9 +4,9 @@
// RUN: %clang_cc1 -std=c++1z -fcxx-exceptions -fms-extensions -DMS -fexceptions -verify %s
// RUN: %clang_cc1 -std=c++2a -fcxx-exceptions -fms-extensions -DMS -DUSE_CONSTEVAL -fexceptions -verify %s
//
-/// FIXME: The -DPAREN_INIT one is missing for the new interpreter.
// RUN: %clang_cc1 -std=c++1z -fcxx-exceptions -fexceptions -fexperimental-new-constant-interpreter -DNEW_INTERP -verify %s
// RUN: %clang_cc1 -std=c++2a -fcxx-exceptions -DUSE_CONSTEVAL -fexceptions -fexperimental-new-constant-interpreter -DNEW_INTERP -verify %s
+// RUN: %clang_cc1 -std=c++2b -fcxx-exceptions -DUSE_CONSTEVAL -DPAREN_INIT -fexceptions -fexperimental-new-constant-interpreter -DNEW_INTERP -verify %s
// RUN: %clang_cc1 -std=c++1z -fcxx-exceptions -fms-extensions -DMS -fexceptions -fexperimental-new-constant-interpreter -DNEW_INTERP -verify %s
// RUN: %clang_cc1 -std=c++2a -fcxx-exceptions -fms-extensions -DMS -DUSE_CONSTEVAL -fexceptions -fexperimental-new-constant-interpreter -DNEW_INTERP -verify %s
// expected-no-diagnostics
More information about the cfe-commits
mailing list