Revise DValue repainting (#3991)

Fixes #3990.
This commit is contained in:
Martin Kinkelin 2022-07-12 13:40:02 +02:00 committed by GitHub
parent 8863a801e9
commit aa59b5a2a2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 61 additions and 50 deletions

View file

@ -13,6 +13,7 @@
- Supports LLVM 9.0 - 14.0. - Supports LLVM 9.0 - 14.0.
#### Bug fixes #### Bug fixes
- Report unexpected type repaints as fatal ICEs instead of crashing. (#3990, #3991)
#### Internals #### Internals
- Main CI was moved from Azure Pipelines to GitHub Actions. Any fork on GitHub can trivially reuse the fully automated prebuilt packages generation & upload to a GitHub release. (#3978) - Main CI was moved from Azure Pipelines to GitHub Actions. Any fork on GitHub can trivially reuse the fully automated prebuilt packages generation & upload to a GitHub release. (#3978)

View file

@ -771,58 +771,45 @@ DValue *DtoPaintType(const Loc &loc, DValue *val, Type *to) {
IF_LOG Logger::println("repainting from '%s' to '%s'", from->toChars(), IF_LOG Logger::println("repainting from '%s' to '%s'", from->toChars(),
to->toChars()); to->toChars());
if (from->ty == TY::Tarray) { Type *tb = to->toBasetype();
Type *at = to->toBasetype();
assert(at->ty == TY::Tarray);
Type *elem = at->nextOf()->pointerTo();
if (DSliceValue *slice = val->isSlice()) {
return new DSliceValue(to, slice->getLength(),
DtoBitCast(slice->getPtr(), DtoType(elem)));
}
if (val->isLVal()) { if (val->isLVal()) {
LLValue *ptr = DtoLVal(val); auto ptr = DtoBitCast(DtoLVal(val), DtoPtrToType(tb));
ptr = DtoBitCast(ptr, DtoType(at->pointerTo()));
return new DLValue(to, ptr); return new DLValue(to, ptr);
} }
LLValue *len, *ptr;
len = DtoArrayLen(val); if (auto slice = val->isSlice()) {
ptr = DtoArrayPtr(val); if (tb->ty == TY::Tarray) {
ptr = DtoBitCast(ptr, DtoType(elem)); auto ptr = DtoBitCast(slice->getPtr(), DtoPtrToType(tb->nextOf()));
return new DImValue(to, DtoAggrPair(len, ptr)); return new DSliceValue(to, slice->getLength(), ptr);
} }
if (from->ty == TY::Tdelegate) { } else if (auto func = val->isFunc()) {
Type *dgty = to->toBasetype(); if (tb->ty == TY::Tdelegate) {
assert(dgty->ty == TY::Tdelegate); auto funcptr =
if (val->isLVal()) { DtoBitCast(DtoRVal(func), DtoType(tb)->getContainedType(1));
LLValue *ptr = DtoLVal(val); return new DFuncValue(to, func->func, funcptr, func->vthis);
assert(isaPointer(ptr));
ptr = DtoBitCast(ptr, DtoPtrToType(dgty));
IF_LOG Logger::cout() << "dg ptr: " << *ptr << '\n';
return new DLValue(to, ptr);
} }
LLValue *dg = DtoRVal(val); } else { // generic rvalue
LLValue *context = gIR->ir->CreateExtractValue(dg, 0, ".context"); LLValue *rval = DtoRVal(val);
LLValue *funcptr = gIR->ir->CreateExtractValue(dg, 1, ".funcptr"); LLType *tll = DtoType(tb);
funcptr = DtoBitCast(funcptr, DtoType(dgty)->getContainedType(1));
LLValue *aggr = DtoAggrPair(context, funcptr); if (rval->getType() == tll) {
IF_LOG Logger::cout() << "dg: " << *aggr << '\n'; return new DImValue(to, rval);
return new DImValue(to, aggr);
} }
if (from->ty == TY::Tpointer || from->ty == TY::Tclass || if (rval->getType()->isPointerTy() && tll->isPointerTy()) {
from->ty == TY::Taarray) { return new DImValue(to, DtoBitCast(rval, tll));
Type *b = to->toBasetype();
assert(b->ty == TY::Tpointer || b->ty == TY::Tclass ||
b->ty == TY::Taarray);
LLValue *ptr = DtoBitCast(DtoRVal(val), DtoType(b));
return new DImValue(to, ptr);
} }
if (from->ty == TY::Tsarray) { if (from->ty == TY::Tdelegate && tb->ty == TY::Tdelegate) {
assert(to->toBasetype()->ty == TY::Tsarray); LLValue *context = gIR->ir->CreateExtractValue(rval, 0, ".context");
LLValue *ptr = DtoBitCast(DtoLVal(val), DtoPtrToType(to)); LLValue *funcptr = gIR->ir->CreateExtractValue(rval, 1, ".funcptr");
return new DLValue(to, ptr); funcptr = DtoBitCast(funcptr, tll->getContainedType(1));
return new DImValue(to, DtoAggrPair(context, funcptr));
} }
assert(DtoType(from) == DtoType(to)); }
return new DImValue(to, DtoRVal(val));
error(loc, "ICE: unexpected type repaint from `%s` to `%s`", from->toChars(),
to->toChars());
fatal();
} }
/****************************************************************************** /******************************************************************************

23
tests/compilable/gh3990.d Normal file
View file

@ -0,0 +1,23 @@
// RUN: %ldc -c %s
struct Vector
{
float x, y, z;
}
struct QAngle
{
float x, y, z;
QAngle opOpAssign(string op)(const(QAngle))
{
return this;
}
}
void OnUserCmdPre()
{
Vector ss;
QAngle dd;
dd -= cast(QAngle)ss;
}