mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-06 19:06:02 +03:00
parent
8863a801e9
commit
aa59b5a2a2
3 changed files with 61 additions and 50 deletions
|
@ -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)
|
||||||
|
|
|
@ -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
23
tests/compilable/gh3990.d
Normal 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;
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue