Skip to content

Commit 30cf01d

Browse files
Merge branch 'llvm:main' into gh-101657
2 parents 05be756 + b5a11d3 commit 30cf01d

File tree

8 files changed

+352
-274
lines changed

8 files changed

+352
-274
lines changed

clang/lib/AST/ByteCode/Compiler.cpp

Lines changed: 51 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1642,22 +1642,8 @@ bool Compiler<Emitter>::VisitImplicitValueInitExpr(
16421642
if (QT->isIncompleteArrayType())
16431643
return true;
16441644

1645-
if (QT->isArrayType()) {
1646-
const ArrayType *AT = QT->getAsArrayTypeUnsafe();
1647-
assert(AT);
1648-
const auto *CAT = cast<ConstantArrayType>(AT);
1649-
size_t NumElems = CAT->getZExtSize();
1650-
PrimType ElemT = classifyPrim(CAT->getElementType());
1651-
1652-
for (size_t I = 0; I != NumElems; ++I) {
1653-
if (!this->visitZeroInitializer(ElemT, CAT->getElementType(), E))
1654-
return false;
1655-
if (!this->emitInitElem(ElemT, I, E))
1656-
return false;
1657-
}
1658-
1659-
return true;
1660-
}
1645+
if (QT->isArrayType())
1646+
return this->visitZeroArrayInitializer(QT, E);
16611647

16621648
if (const auto *ComplexTy = E->getType()->getAs<ComplexType>()) {
16631649
assert(Initializing);
@@ -3916,18 +3902,9 @@ bool Compiler<Emitter>::visitZeroRecordInitializer(const Record *R,
39163902
return false;
39173903
}
39183904
} else if (D->isCompositeArray()) {
3919-
const Record *ElemRecord = D->ElemDesc->ElemRecord;
3920-
assert(D->ElemDesc->ElemRecord);
3921-
for (uint32_t I = 0, N = D->getNumElems(); I != N; ++I) {
3922-
if (!this->emitConstUint32(I, E))
3923-
return false;
3924-
if (!this->emitArrayElemPtr(PT_Uint32, E))
3925-
return false;
3926-
if (!this->visitZeroRecordInitializer(ElemRecord, E))
3927-
return false;
3928-
if (!this->emitPopPtr(E))
3929-
return false;
3930-
}
3905+
// Can't be a vector or complex field.
3906+
if (!this->visitZeroArrayInitializer(D->getType(), E))
3907+
return false;
39313908
} else if (D->isRecord()) {
39323909
if (!this->visitZeroRecordInitializer(D->ElemRecord, E))
39333910
return false;
@@ -3958,6 +3935,52 @@ bool Compiler<Emitter>::visitZeroRecordInitializer(const Record *R,
39583935
return true;
39593936
}
39603937

3938+
template <class Emitter>
3939+
bool Compiler<Emitter>::visitZeroArrayInitializer(QualType T, const Expr *E) {
3940+
assert(T->isArrayType() || T->isAnyComplexType() || T->isVectorType());
3941+
const ArrayType *AT = T->getAsArrayTypeUnsafe();
3942+
QualType ElemType = AT->getElementType();
3943+
size_t NumElems = cast<ConstantArrayType>(AT)->getZExtSize();
3944+
3945+
if (std::optional<PrimType> ElemT = classify(ElemType)) {
3946+
for (size_t I = 0; I != NumElems; ++I) {
3947+
if (!this->visitZeroInitializer(*ElemT, ElemType, E))
3948+
return false;
3949+
if (!this->emitInitElem(*ElemT, I, E))
3950+
return false;
3951+
}
3952+
return true;
3953+
} else if (ElemType->isRecordType()) {
3954+
const Record *R = getRecord(ElemType);
3955+
3956+
for (size_t I = 0; I != NumElems; ++I) {
3957+
if (!this->emitConstUint32(I, E))
3958+
return false;
3959+
if (!this->emitArrayElemPtr(PT_Uint32, E))
3960+
return false;
3961+
if (!this->visitZeroRecordInitializer(R, E))
3962+
return false;
3963+
if (!this->emitPopPtr(E))
3964+
return false;
3965+
}
3966+
return true;
3967+
} else if (ElemType->isArrayType()) {
3968+
for (size_t I = 0; I != NumElems; ++I) {
3969+
if (!this->emitConstUint32(I, E))
3970+
return false;
3971+
if (!this->emitArrayElemPtr(PT_Uint32, E))
3972+
return false;
3973+
if (!this->visitZeroArrayInitializer(ElemType, E))
3974+
return false;
3975+
if (!this->emitPopPtr(E))
3976+
return false;
3977+
}
3978+
return true;
3979+
}
3980+
3981+
return false;
3982+
}
3983+
39613984
template <class Emitter>
39623985
template <typename T>
39633986
bool Compiler<Emitter>::emitConst(T Value, PrimType Ty, const Expr *E) {

clang/lib/AST/ByteCode/Compiler.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,7 @@ class Compiler : public ConstStmtVisitor<Compiler<Emitter>, bool>,
325325
/// Emits a zero initializer.
326326
bool visitZeroInitializer(PrimType T, QualType QT, const Expr *E);
327327
bool visitZeroRecordInitializer(const Record *R, const Expr *E);
328+
bool visitZeroArrayInitializer(QualType T, const Expr *E);
328329

329330
/// Emits an APSInt constant.
330331
bool emitConst(const llvm::APSInt &Value, PrimType Ty, const Expr *E);

clang/lib/AST/ByteCode/InterpFrame.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,12 @@ SourceInfo InterpFrame::getSource(CodePtr PC) const {
234234
if (Func && !funcHasUsableBody(Func) && Caller)
235235
return Caller->getSource(RetPC);
236236

237-
return S.getSource(Func, PC);
237+
// Similarly, if the resulting source location is invalid anyway,
238+
// point to the caller instead.
239+
SourceInfo Result = S.getSource(Func, PC);
240+
if (Result.getLoc().isInvalid() && Caller)
241+
return Caller->getSource(RetPC);
242+
return Result;
238243
}
239244

240245
const Expr *InterpFrame::getExpr(CodePtr PC) const {

clang/test/AST/ByteCode/placement-new.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %clang_cc1 -std=c++2c -fcxx-exceptions -fexperimental-new-constant-interpreter -verify=expected,both %s
1+
// RUN: %clang_cc1 -std=c++2c -fcxx-exceptions -fexperimental-new-constant-interpreter -verify=expected,both %s -DBYTECODE
22
// RUN: %clang_cc1 -std=c++2c -fcxx-exceptions -verify=ref,both %s
33

44
namespace std {
@@ -338,3 +338,17 @@ namespace PR48606 {
338338
}
339339
static_assert(f());
340340
}
341+
342+
#ifdef BYTECODE
343+
constexpr int N = [] // expected-error {{must be initialized by a constant expression}} \
344+
// expected-note {{assignment to dereferenced one-past-the-end pointer is not allowed in a constant expression}} \
345+
// expected-note {{in call to}}
346+
{
347+
struct S {
348+
int a[1];
349+
};
350+
S s;
351+
::new (s.a) int[1][2][3][4]();
352+
return s.a[0];
353+
}();
354+
#endif

0 commit comments

Comments
 (0)