Skip to content

Commit 93bb5c6

Browse files
authored
[clang][bytecode] Fix CXXConstructExpr for multidim arrays (#164760)
This is a thing apparently. Fixes #153803
1 parent e4c3084 commit 93bb5c6

File tree

2 files changed

+40
-20
lines changed

2 files changed

+40
-20
lines changed

clang/lib/AST/ByteCode/Compiler.cpp

Lines changed: 29 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3273,34 +3273,43 @@ bool Compiler<Emitter>::VisitCXXConstructExpr(const CXXConstructExpr *E) {
32733273
}
32743274

32753275
if (T->isArrayType()) {
3276-
const ConstantArrayType *CAT =
3277-
Ctx.getASTContext().getAsConstantArrayType(E->getType());
3278-
if (!CAT)
3279-
return false;
3280-
3281-
size_t NumElems = CAT->getZExtSize();
32823276
const Function *Func = getFunction(E->getConstructor());
32833277
if (!Func)
32843278
return false;
32853279

3286-
// FIXME(perf): We're calling the constructor once per array element here,
3287-
// in the old intepreter we had a special-case for trivial constructors.
3288-
for (size_t I = 0; I != NumElems; ++I) {
3289-
if (!this->emitConstUint64(I, E))
3290-
return false;
3291-
if (!this->emitArrayElemPtrUint64(E))
3292-
return false;
3280+
if (!this->emitDupPtr(E))
3281+
return false;
32933282

3294-
// Constructor arguments.
3295-
for (const auto *Arg : E->arguments()) {
3296-
if (!this->visit(Arg))
3297-
return false;
3283+
std::function<bool(QualType)> initArrayDimension;
3284+
initArrayDimension = [&](QualType T) -> bool {
3285+
if (!T->isArrayType()) {
3286+
// Constructor arguments.
3287+
for (const auto *Arg : E->arguments()) {
3288+
if (!this->visit(Arg))
3289+
return false;
3290+
}
3291+
3292+
return this->emitCall(Func, 0, E);
32983293
}
32993294

3300-
if (!this->emitCall(Func, 0, E))
3295+
const ConstantArrayType *CAT =
3296+
Ctx.getASTContext().getAsConstantArrayType(T);
3297+
if (!CAT)
33013298
return false;
3302-
}
3303-
return true;
3299+
QualType ElemTy = CAT->getElementType();
3300+
unsigned NumElems = CAT->getZExtSize();
3301+
for (size_t I = 0; I != NumElems; ++I) {
3302+
if (!this->emitConstUint64(I, E))
3303+
return false;
3304+
if (!this->emitArrayElemPtrUint64(E))
3305+
return false;
3306+
if (!initArrayDimension(ElemTy))
3307+
return false;
3308+
}
3309+
return this->emitPopPtr(E);
3310+
};
3311+
3312+
return initArrayDimension(E->getType());
33043313
}
33053314

33063315
return false;

clang/test/AST/ByteCode/arrays.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -820,3 +820,14 @@ namespace FAM {
820820
return 1;
821821
}
822822
}
823+
824+
namespace MultiDimConstructExpr {
825+
struct a {
826+
a *p = this;
827+
};
828+
struct b {
829+
a m[3][3];
830+
};
831+
constexpr b d;
832+
static_assert(d.m[2][1].p == &d.m[2][1]);
833+
}

0 commit comments

Comments
 (0)