Skip to content

Commit

Permalink
Revise DValue repainting (ldc-developers#3991)
Browse files Browse the repository at this point in the history
  • Loading branch information
kinke authored Jul 12, 2022
1 parent 8863a80 commit aa59b5a
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 48 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
- Supports LLVM 9.0 - 14.0.

#### Bug fixes
- Report unexpected type repaints as fatal ICEs instead of crashing. (#3990, #3991)

#### 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)
Expand Down
83 changes: 35 additions & 48 deletions gen/llvmhelpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -771,58 +771,45 @@ DValue *DtoPaintType(const Loc &loc, DValue *val, Type *to) {
IF_LOG Logger::println("repainting from '%s' to '%s'", from->toChars(),
to->toChars());

if (from->ty == TY::Tarray) {
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)));
Type *tb = to->toBasetype();

if (val->isLVal()) {
auto ptr = DtoBitCast(DtoLVal(val), DtoPtrToType(tb));
return new DLValue(to, ptr);
}

if (auto slice = val->isSlice()) {
if (tb->ty == TY::Tarray) {
auto ptr = DtoBitCast(slice->getPtr(), DtoPtrToType(tb->nextOf()));
return new DSliceValue(to, slice->getLength(), ptr);
}
if (val->isLVal()) {
LLValue *ptr = DtoLVal(val);
ptr = DtoBitCast(ptr, DtoType(at->pointerTo()));
return new DLValue(to, ptr);
} else if (auto func = val->isFunc()) {
if (tb->ty == TY::Tdelegate) {
auto funcptr =
DtoBitCast(DtoRVal(func), DtoType(tb)->getContainedType(1));
return new DFuncValue(to, func->func, funcptr, func->vthis);
}
LLValue *len, *ptr;
len = DtoArrayLen(val);
ptr = DtoArrayPtr(val);
ptr = DtoBitCast(ptr, DtoType(elem));
return new DImValue(to, DtoAggrPair(len, ptr));
}
if (from->ty == TY::Tdelegate) {
Type *dgty = to->toBasetype();
assert(dgty->ty == TY::Tdelegate);
if (val->isLVal()) {
LLValue *ptr = DtoLVal(val);
assert(isaPointer(ptr));
ptr = DtoBitCast(ptr, DtoPtrToType(dgty));
IF_LOG Logger::cout() << "dg ptr: " << *ptr << '\n';
return new DLValue(to, ptr);
} else { // generic rvalue
LLValue *rval = DtoRVal(val);
LLType *tll = DtoType(tb);

if (rval->getType() == tll) {
return new DImValue(to, rval);
}
if (rval->getType()->isPointerTy() && tll->isPointerTy()) {
return new DImValue(to, DtoBitCast(rval, tll));
}
if (from->ty == TY::Tdelegate && tb->ty == TY::Tdelegate) {
LLValue *context = gIR->ir->CreateExtractValue(rval, 0, ".context");
LLValue *funcptr = gIR->ir->CreateExtractValue(rval, 1, ".funcptr");
funcptr = DtoBitCast(funcptr, tll->getContainedType(1));
return new DImValue(to, DtoAggrPair(context, funcptr));
}
LLValue *dg = DtoRVal(val);
LLValue *context = gIR->ir->CreateExtractValue(dg, 0, ".context");
LLValue *funcptr = gIR->ir->CreateExtractValue(dg, 1, ".funcptr");
funcptr = DtoBitCast(funcptr, DtoType(dgty)->getContainedType(1));
LLValue *aggr = DtoAggrPair(context, funcptr);
IF_LOG Logger::cout() << "dg: " << *aggr << '\n';
return new DImValue(to, aggr);
}
if (from->ty == TY::Tpointer || from->ty == TY::Tclass ||
from->ty == TY::Taarray) {
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) {
assert(to->toBasetype()->ty == TY::Tsarray);
LLValue *ptr = DtoBitCast(DtoLVal(val), DtoPtrToType(to));
return new DLValue(to, ptr);
}
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();
}

/******************************************************************************
Expand Down
23 changes: 23 additions & 0 deletions tests/compilable/gh3990.d
Original file line number Diff line number Diff line change
@@ -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;
}

0 comments on commit aa59b5a

Please sign in to comment.