Skip to content

Commit a5f9b16

Browse files
author
git apple-llvm automerger
committed
Merge commit 'e34b41c707a8' from llvm.org/main into next
2 parents 47f4113 + e34b41c commit a5f9b16

File tree

3 files changed

+109
-110
lines changed

3 files changed

+109
-110
lines changed

clang/lib/AST/Interp/ByteCodeExprGen.cpp

Lines changed: 101 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -1023,139 +1023,112 @@ bool ByteCodeExprGen<Emitter>::VisitArraySubscriptExpr(
10231023

10241024
template <class Emitter>
10251025
bool ByteCodeExprGen<Emitter>::visitInitList(ArrayRef<const Expr *> Inits,
1026+
const Expr *ArrayFiller,
10261027
const Expr *E) {
1027-
assert(E->getType()->isRecordType());
1028-
const Record *R = getRecord(E->getType());
1028+
if (E->getType()->isVoidType())
1029+
return this->emitInvalid(E);
10291030

1030-
if (Inits.size() == 1 && E->getType() == Inits[0]->getType()) {
1031-
return this->visitInitializer(Inits[0]);
1031+
// Handle discarding first.
1032+
if (DiscardResult) {
1033+
for (const Expr *Init : Inits) {
1034+
if (!this->discard(Init))
1035+
return false;
1036+
}
1037+
return true;
10321038
}
10331039

1034-
unsigned InitIndex = 0;
1035-
for (const Expr *Init : Inits) {
1036-
// Skip unnamed bitfields.
1037-
while (InitIndex < R->getNumFields() &&
1038-
R->getField(InitIndex)->Decl->isUnnamedBitField())
1039-
++InitIndex;
1040+
// Primitive values.
1041+
if (std::optional<PrimType> T = classify(E->getType())) {
1042+
assert(!DiscardResult);
1043+
if (Inits.size() == 0)
1044+
return this->visitZeroInitializer(*T, E->getType(), E);
1045+
assert(Inits.size() == 1);
1046+
return this->delegate(Inits[0]);
1047+
}
10401048

1041-
if (!this->emitDupPtr(E))
1042-
return false;
1049+
QualType T = E->getType();
1050+
if (T->isRecordType()) {
1051+
const Record *R = getRecord(E->getType());
10431052

1044-
if (std::optional<PrimType> T = classify(Init)) {
1045-
const Record::Field *FieldToInit = R->getField(InitIndex);
1046-
if (!this->visit(Init))
1047-
return false;
1053+
if (Inits.size() == 1 && E->getType() == Inits[0]->getType()) {
1054+
return this->visitInitializer(Inits[0]);
1055+
}
10481056

1049-
if (FieldToInit->isBitField()) {
1050-
if (!this->emitInitBitField(*T, FieldToInit, E))
1051-
return false;
1052-
} else {
1053-
if (!this->emitInitField(*T, FieldToInit->Offset, E))
1054-
return false;
1055-
}
1057+
unsigned InitIndex = 0;
1058+
for (const Expr *Init : Inits) {
1059+
// Skip unnamed bitfields.
1060+
while (InitIndex < R->getNumFields() &&
1061+
R->getField(InitIndex)->Decl->isUnnamedBitField())
1062+
++InitIndex;
10561063

1057-
if (!this->emitPopPtr(E))
1064+
if (!this->emitDupPtr(E))
10581065
return false;
1059-
++InitIndex;
1060-
} else {
1061-
// Initializer for a direct base class.
1062-
if (const Record::Base *B = R->getBase(Init->getType())) {
1063-
if (!this->emitGetPtrBasePop(B->Offset, Init))
1064-
return false;
1065-
1066-
if (!this->visitInitializer(Init))
1067-
return false;
10681066

1069-
if (!this->emitFinishInitPop(E))
1070-
return false;
1071-
// Base initializers don't increase InitIndex, since they don't count
1072-
// into the Record's fields.
1073-
} else {
1067+
if (std::optional<PrimType> T = classify(Init)) {
10741068
const Record::Field *FieldToInit = R->getField(InitIndex);
1075-
// Non-primitive case. Get a pointer to the field-to-initialize
1076-
// on the stack and recurse into visitInitializer().
1077-
if (!this->emitGetPtrField(FieldToInit->Offset, Init))
1069+
if (!this->visit(Init))
10781070
return false;
10791071

1080-
if (!this->visitInitializer(Init))
1081-
return false;
1072+
if (FieldToInit->isBitField()) {
1073+
if (!this->emitInitBitField(*T, FieldToInit, E))
1074+
return false;
1075+
} else {
1076+
if (!this->emitInitField(*T, FieldToInit->Offset, E))
1077+
return false;
1078+
}
10821079

10831080
if (!this->emitPopPtr(E))
10841081
return false;
10851082
++InitIndex;
1086-
}
1087-
}
1088-
}
1089-
return true;
1090-
}
1083+
} else {
1084+
// Initializer for a direct base class.
1085+
if (const Record::Base *B = R->getBase(Init->getType())) {
1086+
if (!this->emitGetPtrBasePop(B->Offset, Init))
1087+
return false;
10911088

1092-
/// Pointer to the array(not the element!) must be on the stack when calling
1093-
/// this.
1094-
template <class Emitter>
1095-
bool ByteCodeExprGen<Emitter>::visitArrayElemInit(unsigned ElemIndex,
1096-
const Expr *Init) {
1097-
if (std::optional<PrimType> T = classify(Init->getType())) {
1098-
// Visit the primitive element like normal.
1099-
if (!this->visit(Init))
1100-
return false;
1101-
return this->emitInitElem(*T, ElemIndex, Init);
1102-
}
1089+
if (!this->visitInitializer(Init))
1090+
return false;
11031091

1104-
// Advance the pointer currently on the stack to the given
1105-
// dimension.
1106-
if (!this->emitConstUint32(ElemIndex, Init))
1107-
return false;
1108-
if (!this->emitArrayElemPtrUint32(Init))
1109-
return false;
1110-
if (!this->visitInitializer(Init))
1111-
return false;
1112-
return this->emitFinishInitPop(Init);
1113-
}
1092+
if (!this->emitFinishInitPop(E))
1093+
return false;
1094+
// Base initializers don't increase InitIndex, since they don't count
1095+
// into the Record's fields.
1096+
} else {
1097+
const Record::Field *FieldToInit = R->getField(InitIndex);
1098+
// Non-primitive case. Get a pointer to the field-to-initialize
1099+
// on the stack and recurse into visitInitializer().
1100+
if (!this->emitGetPtrField(FieldToInit->Offset, Init))
1101+
return false;
11141102

1115-
template <class Emitter>
1116-
bool ByteCodeExprGen<Emitter>::VisitInitListExpr(const InitListExpr *E) {
1117-
if (E->getType()->isVoidType())
1118-
return this->emitInvalid(E);
1103+
if (!this->visitInitializer(Init))
1104+
return false;
11191105

1120-
// Handle discarding first.
1121-
if (DiscardResult) {
1122-
for (const Expr *Init : E->inits()) {
1123-
if (!this->discard(Init))
1124-
return false;
1106+
if (!this->emitPopPtr(E))
1107+
return false;
1108+
++InitIndex;
1109+
}
1110+
}
11251111
}
11261112
return true;
11271113
}
11281114

1129-
// Primitive values.
1130-
if (std::optional<PrimType> T = classify(E->getType())) {
1131-
assert(!DiscardResult);
1132-
if (E->getNumInits() == 0)
1133-
return this->visitZeroInitializer(*T, E->getType(), E);
1134-
assert(E->getNumInits() == 1);
1135-
return this->delegate(E->inits()[0]);
1136-
}
1137-
1138-
QualType T = E->getType();
1139-
if (T->isRecordType())
1140-
return this->visitInitList(E->inits(), E);
1141-
11421115
if (T->isArrayType()) {
11431116
unsigned ElementIndex = 0;
1144-
for (const Expr *Init : E->inits()) {
1117+
for (const Expr *Init : Inits) {
11451118
if (!this->visitArrayElemInit(ElementIndex, Init))
11461119
return false;
11471120
++ElementIndex;
11481121
}
11491122

11501123
// Expand the filler expression.
11511124
// FIXME: This should go away.
1152-
if (const Expr *Filler = E->getArrayFiller()) {
1125+
if (ArrayFiller) {
11531126
const ConstantArrayType *CAT =
11541127
Ctx.getASTContext().getAsConstantArrayType(E->getType());
11551128
uint64_t NumElems = CAT->getZExtSize();
11561129

11571130
for (; ElementIndex != NumElems; ++ElementIndex) {
1158-
if (!this->visitArrayElemInit(ElementIndex, Filler))
1131+
if (!this->visitArrayElemInit(ElementIndex, ArrayFiller))
11591132
return false;
11601133
}
11611134
}
@@ -1164,10 +1137,10 @@ bool ByteCodeExprGen<Emitter>::VisitInitListExpr(const InitListExpr *E) {
11641137
}
11651138

11661139
if (const auto *ComplexTy = E->getType()->getAs<ComplexType>()) {
1167-
unsigned NumInits = E->getNumInits();
1140+
unsigned NumInits = Inits.size();
11681141

11691142
if (NumInits == 1)
1170-
return this->delegate(E->inits()[0]);
1143+
return this->delegate(Inits[0]);
11711144

11721145
QualType ElemQT = ComplexTy->getElementType();
11731146
PrimType ElemT = classifyPrim(ElemQT);
@@ -1181,7 +1154,7 @@ bool ByteCodeExprGen<Emitter>::VisitInitListExpr(const InitListExpr *E) {
11811154
}
11821155
} else if (NumInits == 2) {
11831156
unsigned InitIndex = 0;
1184-
for (const Expr *Init : E->inits()) {
1157+
for (const Expr *Init : Inits) {
11851158
if (!this->visit(Init))
11861159
return false;
11871160

@@ -1195,14 +1168,14 @@ bool ByteCodeExprGen<Emitter>::VisitInitListExpr(const InitListExpr *E) {
11951168

11961169
if (const auto *VecT = E->getType()->getAs<VectorType>()) {
11971170
unsigned NumVecElements = VecT->getNumElements();
1198-
assert(NumVecElements >= E->getNumInits());
1171+
assert(NumVecElements >= Inits.size());
11991172

12001173
QualType ElemQT = VecT->getElementType();
12011174
PrimType ElemT = classifyPrim(ElemQT);
12021175

12031176
// All initializer elements.
12041177
unsigned InitIndex = 0;
1205-
for (const Expr *Init : E->inits()) {
1178+
for (const Expr *Init : Inits) {
12061179
if (!this->visit(Init))
12071180
return false;
12081181

@@ -1224,19 +1197,38 @@ bool ByteCodeExprGen<Emitter>::VisitInitListExpr(const InitListExpr *E) {
12241197
return false;
12251198
}
12261199

1200+
/// Pointer to the array(not the element!) must be on the stack when calling
1201+
/// this.
1202+
template <class Emitter>
1203+
bool ByteCodeExprGen<Emitter>::visitArrayElemInit(unsigned ElemIndex,
1204+
const Expr *Init) {
1205+
if (std::optional<PrimType> T = classify(Init->getType())) {
1206+
// Visit the primitive element like normal.
1207+
if (!this->visit(Init))
1208+
return false;
1209+
return this->emitInitElem(*T, ElemIndex, Init);
1210+
}
1211+
1212+
// Advance the pointer currently on the stack to the given
1213+
// dimension.
1214+
if (!this->emitConstUint32(ElemIndex, Init))
1215+
return false;
1216+
if (!this->emitArrayElemPtrUint32(Init))
1217+
return false;
1218+
if (!this->visitInitializer(Init))
1219+
return false;
1220+
return this->emitFinishInitPop(Init);
1221+
}
1222+
1223+
template <class Emitter>
1224+
bool ByteCodeExprGen<Emitter>::VisitInitListExpr(const InitListExpr *E) {
1225+
return this->visitInitList(E->inits(), E->getArrayFiller(), E);
1226+
}
1227+
12271228
template <class Emitter>
12281229
bool ByteCodeExprGen<Emitter>::VisitCXXParenListInitExpr(
12291230
const CXXParenListInitExpr *E) {
1230-
if (DiscardResult) {
1231-
for (const Expr *Init : E->getInitExprs()) {
1232-
if (!this->discard(Init))
1233-
return false;
1234-
}
1235-
return true;
1236-
}
1237-
1238-
assert(E->getType()->isRecordType());
1239-
return this->visitInitList(E->getInitExprs(), E);
1231+
return this->visitInitList(E->getInitExprs(), E->getArrayFiller(), E);
12401232
}
12411233

12421234
template <class Emitter>

clang/lib/AST/Interp/ByteCodeExprGen.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,8 @@ class ByteCodeExprGen : public ConstStmtVisitor<ByteCodeExprGen<Emitter>, bool>,
225225
return this->emitFinishInitPop(I);
226226
}
227227

228-
bool visitInitList(ArrayRef<const Expr *> Inits, const Expr *E);
228+
bool visitInitList(ArrayRef<const Expr *> Inits, const Expr *ArrayFiller,
229+
const Expr *E);
229230
bool visitArrayElemInit(unsigned ElemIndex, const Expr *Init);
230231

231232
/// Creates a local primitive value.

clang/test/AST/Interp/records.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1030,6 +1030,12 @@ namespace ParenInit {
10301030
// both-note {{required by 'constinit' specifier}} \
10311031
// both-note {{reference to temporary is not a constant expression}} \
10321032
// both-note {{temporary created here}}
1033+
1034+
1035+
/// Initializing an array.
1036+
constexpr void bar(int i, int j) {
1037+
int arr[4](i, j);
1038+
}
10331039
}
10341040
#endif
10351041

0 commit comments

Comments
 (0)