Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/cppmangle.c
Original file line number Diff line number Diff line change
Expand Up @@ -428,7 +428,7 @@ static int argsCppMangleDg(void *ctx, size_t n, Parameter *arg)
{
ArgsCppMangleCtx *p = (ArgsCppMangleCtx *)ctx;

Type *t = arg->type;
Type *t = arg->type->merge2();
if (arg->storageClass & (STCout | STCref))
t = t->referenceTo();
else if (arg->storageClass & STClazy)
Expand Down
6 changes: 3 additions & 3 deletions src/ctfeexpr.c
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ Expression *copyLiteral(Expression *e)
*/
Expression *paintTypeOntoLiteral(Type *type, Expression *lit)
{
if (lit->type == type)
if (lit->type->equals(type))
return lit;
Expression *e;
if (lit->op == TOKslice)
Expand Down Expand Up @@ -1758,10 +1758,10 @@ void recursiveBlockAssign(ArrayLiteralExp *ae, Expression *val, bool wantRef)
assert( ae->type->ty == Tsarray || ae->type->ty == Tarray);
#if DMDV2
Type *desttype = ((TypeArray *)ae->type)->next->castMod(0);
bool directblk = (val->type->toBasetype()->castMod(0)) == desttype;
bool directblk = (val->type->toBasetype()->castMod(0))->equals(desttype);
#else
Type *desttype = ((TypeArray *)ae->type)->next;
bool directblk = (val->type->toBasetype()) == desttype;
bool directblk = (val->type->toBasetype())->equals(desttype);
#endif

bool cow = !(val->op == TOKstructliteral || val->op == TOKarrayliteral
Expand Down
7 changes: 7 additions & 0 deletions src/declaration.c
Original file line number Diff line number Diff line change
Expand Up @@ -562,6 +562,13 @@ void AliasDeclaration::semantic(Scope *sc)
else if (t)
{
type = t->semantic(loc, sc);

/* TypeTuple might have extra info,
* is(typeof(func) PT == __parameters)
* Otherwise, strip all redundant informations.
*/
if (type->ty != Ttuple)
type = type->merge2();
//printf("\talias resolved to type %s\n", type->toChars());
}
if (overnext)
Expand Down
5 changes: 3 additions & 2 deletions src/expression.c
Original file line number Diff line number Diff line change
Expand Up @@ -1322,7 +1322,7 @@ Type *functionParameters(Loc loc, Scope *sc, TypeFunction *tf,

if (!arg)
{
if (!p->defaultArg || !fd)
if (!p->defaultArg)
{
if (tf->varargs == 2 && i + 1 == nparams)
goto L2;
Expand Down Expand Up @@ -1483,7 +1483,7 @@ Type *functionParameters(Loc loc, Scope *sc, TypeFunction *tf,
arg = arg->implicitCastTo(sc, p->type->substWildTo(wildmatch));
arg = arg->optimize(WANTvalue, p->storageClass & STCref);
}
else if (p->type != arg->type)
else if (!p->type->equals(arg->type))
{
//printf("arg->type = %s, p->type = %s\n", arg->type->toChars(), p->type->toChars());
if (arg->op == TOKtype)
Expand Down Expand Up @@ -13056,6 +13056,7 @@ Expression *CondExp::semantic(Scope *sc)
e2 = e2->castTo(sc, type);
}
}
type = type->merge2();
#if 0
printf("res: %s\n", type->toChars());
printf("e1 : %s\n", e1->type->toChars());
Expand Down
6 changes: 3 additions & 3 deletions src/func.c
Original file line number Diff line number Diff line change
Expand Up @@ -1420,7 +1420,7 @@ void FuncDeclaration::semantic3(Scope *sc)
::error(loc, "%s '%s' is nothrow yet may throw", kind(), toPrettyChars());
if (flags & FUNCFLAGnothrowInprocess)
{
if (type == f) f = f->copy();
if (type == f) f = (TypeFunction *)f->copy();
f->isnothrow = !(blockexit & BEthrow);
}

Expand Down Expand Up @@ -1755,14 +1755,14 @@ void FuncDeclaration::semantic3(Scope *sc)
if (flags & FUNCFLAGpurityInprocess)
{
flags &= ~FUNCFLAGpurityInprocess;
if (type == f) f = f->copy();
if (type == f) f = (TypeFunction *)f->copy();
f->purity = PUREfwdref;
}

if (flags & FUNCFLAGsafetyInprocess)
{
flags &= ~FUNCFLAGsafetyInprocess;
if (type == f) f = f->copy();
if (type == f) f = (TypeFunction *)f->copy();
f->trust = TRUSTsafe;
}

Expand Down
14 changes: 7 additions & 7 deletions src/interpret.c
Original file line number Diff line number Diff line change
Expand Up @@ -3042,9 +3042,9 @@ Expression *BinExp::interpretAssignCommon(InterState *istate, CtfeGoal goal, fp_
{
desttype = ((TypeArray *)desttype)->next;
#if DMDV2
if (srctype == desttype->castMod(0))
if (srctype->equals(desttype->castMod(0)))
#else
if (srctype == desttype)
if (srctype->equals(desttype))
#endif
{
isBlockAssignment = true;
Expand All @@ -3064,7 +3064,7 @@ Expression *BinExp::interpretAssignCommon(InterState *istate, CtfeGoal goal, fp_
bool wantRef = false;
bool wantLvalueRef = false;

if (!fp && this->e1->type->toBasetype() == this->e2->type->toBasetype() &&
if (!fp && this->e1->type->toBasetype()->equals(this->e2->type->toBasetype()) &&
(e1->type->toBasetype()->ty == Tarray || isAssocArray(e1->type)
|| e1->type->toBasetype()->ty == Tclass)
// e = *x is never a reference, because *x is always a value
Expand Down Expand Up @@ -4089,10 +4089,10 @@ Expression *interpretAssignToSlice(InterState *istate, CtfeGoal goal, Loc loc,
existingAE->type->ty == Tarray);
#if DMDV2
Type *desttype = ((TypeArray *)existingAE->type)->next->castMod(0);
bool directblk = (e2->type->toBasetype()->castMod(0)) == desttype;
bool directblk = (e2->type->toBasetype()->castMod(0))->equals(desttype);
#else
Type *desttype = ((TypeArray *)existingAE->type)->next;
bool directblk = (e2->type->toBasetype()) == desttype;
bool directblk = (e2->type->toBasetype())->equals(desttype);
#endif
bool cow = !(newval->op == TOKstructliteral || newval->op == TOKarrayliteral
|| newval->op == TOKstring);
Expand Down Expand Up @@ -5268,7 +5268,7 @@ Expression *CastExp::interpret(InterState *istate, CtfeGoal goal)
e->type = type;
return e;
}
if (e1->op == TOKindex && ((IndexExp *)e1)->e1->type != e1->type)
if (e1->op == TOKindex && !((IndexExp *)e1)->e1->type->equals(e1->type))
{ // type painting operation
IndexExp *ie = (IndexExp *)e1;
e = new IndexExp(e1->loc, ie->e1, ie->e2);
Expand Down Expand Up @@ -5661,7 +5661,7 @@ Expression *DotVarExp::interpret(InterState *istate, CtfeGoal goal)
* CastExp.
*/
if (goal == ctfeNeedLvalue && e->op == TOKindex &&
e->type == type &&
e->type->equals(type) &&
isPointer(type) )
return e;
// ...Otherwise, just return the (simplified) dotvar expression
Expand Down
119 changes: 102 additions & 17 deletions src/mtype.c
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,13 @@ const char *Type::kind()
return NULL;
}

Type *Type::copy()
{
Type *t = (Type *)mem.malloc(sizeTy[ty]);
memcpy(t, this, sizeTy[ty]);
return t;
}

Type *Type::syntaxCopy()
{
print();
Expand Down Expand Up @@ -1176,10 +1183,15 @@ Type *Type::pointerTo()
if (ty == Terror)
return this;
if (!pto)
{ Type *t;

t = new TypePointer(this);
pto = t->merge();
{
Type *t = new TypePointer(this);
if (ty == Tfunction)
{
t->deco = t->merge()->deco;
pto = t;
}
else
pto = t->merge();
}
return pto;
}
Expand Down Expand Up @@ -1596,6 +1608,85 @@ char *Type::modToChars()
return buf.extractData();
}

/************************************
* Strip all parameter's idenfiers and their default arguments for merging types.
* If some of parameter types or return type are function pointer, delegate, or
* the types which contains either, then strip also from them.
*/

Type *stripDefaultArgs(Type *t)
{
struct N
{
static Parameters *stripParams(Parameters *arguments)
{
Parameters *args = arguments;
if (args && args->dim > 0)
{
for (size_t i = 0; i < args->dim; i++)
{
Parameter *a = (*args)[i];
Type *ta = stripDefaultArgs(a->type);
if (ta != a->type || a->defaultArg || a->ident)
{
if (args == arguments)
{
args = new Parameters();
args->setDim(arguments->dim);
for (size_t j = 0; j < args->dim; j++)
(*args)[j] = (*arguments)[j];
}
(*args)[i] = new Parameter(a->storageClass, ta, NULL, NULL);
}
}
}
return args;
}
};

if (t == NULL)
return t;

if (t->ty == Tfunction)
{
TypeFunction *tf = (TypeFunction *)t;
Type *tret = stripDefaultArgs(tf->next);
Parameters *args = N::stripParams(tf->parameters);
if (tret == tf->next && args == tf->parameters)
goto Lnot;
tf = (TypeFunction *)tf->copy();
tf->parameters = args;
tf->next = tret;
//printf("strip %s\n <- %s\n", tf->toChars(), t->toChars());
t = tf;
}
else if (t->ty == Ttuple)
{
TypeTuple *tt = (TypeTuple *)t;
Parameters *args = N::stripParams(tt->arguments);
if (args == tt->arguments)
goto Lnot;
t = new TypeTuple(args);
}
else if (t->ty == Tenum)
{
// TypeEnum::nextOf() may be != NULL, but it's not necessary here.
goto Lnot;
}
else
{
Type *tn = t->nextOf();
Type *n = stripDefaultArgs(tn);
if (n == tn)
goto Lnot;
t = t->copy();
((TypeNext *)t)->next = n;
}
//printf("strip %s\n", t->toChars());
Lnot:
return t;
}

/************************************
*/

Expand Down Expand Up @@ -1633,8 +1724,8 @@ Type *Type::merge()
}
else
{
sv->ptrvalue = this;
deco = (char *)sv->toDchars();
sv->ptrvalue = (t = stripDefaultArgs(t));
deco = t->deco = (char *)sv->toDchars();
//printf("new value, deco = '%s' %p\n", t->deco, t->deco);
}
}
Expand Down Expand Up @@ -4394,6 +4485,7 @@ Type *TypeAArray::semantic(Loc loc, Scope *sc)
}
else
index = index->semantic(loc,sc);
index = index->merge2();

if (index->nextOf() && !index->nextOf()->isImmutable())
{
Expand All @@ -4420,7 +4512,7 @@ printf("index->ito->ito = x%x\n", index->ito->ito);
case Terror:
return Type::terror;
}
next = next->semantic(loc,sc);
next = next->semantic(loc,sc)->merge2();
transitive();

switch (next->toBasetype()->ty)
Expand Down Expand Up @@ -4723,7 +4815,7 @@ Type *TypePointer::semantic(Loc loc, Scope *sc)
{ transitive();
return merge();
}
#if 1
#if 0
return merge();
#else
deco = merge()->deco;
Expand Down Expand Up @@ -4968,13 +5060,6 @@ const char *TypeFunction::kind()
return "function";
}

TypeFunction *TypeFunction::copy()
{
TypeFunction *tf = (TypeFunction *)mem.malloc(sizeof(TypeFunction));
memcpy(tf, this, sizeof(TypeFunction));
return tf;
}

Type *TypeFunction::syntaxCopy()
{
Type *treturn = next ? next->syntaxCopy() : NULL;
Expand Down Expand Up @@ -5406,7 +5491,7 @@ Type *TypeFunction::semantic(Loc loc, Scope *sc)
* This can produce redundant copies if inferring return type,
* as semantic() will get called again on this.
*/
TypeFunction *tf = copy();
TypeFunction *tf = (TypeFunction *)copy();
if (parameters)
{ tf->parameters = (Parameters *)parameters->copy();
for (size_t i = 0; i < parameters->dim; i++)
Expand Down Expand Up @@ -6123,7 +6208,7 @@ Type *TypeDelegate::semantic(Loc loc, Scope *sc)
* be removed from next before the merge.
*/

#if 1
#if 0
return merge();
#else
/* Don't return merge(), because arg identifiers and default args
Expand Down
2 changes: 1 addition & 1 deletion src/mtype.h
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,7 @@ class Type : public RootObject

Type(TY ty);
virtual const char *kind();
Type *copy();
virtual Type *syntaxCopy();
bool equals(RootObject *o);
int dyncast() { return DYNCAST_TYPE; } // kludge for template.isType()
Expand Down Expand Up @@ -669,7 +670,6 @@ class TypeFunction : public TypeNext

TypeFunction(Parameters *parameters, Type *treturn, int varargs, LINK linkage, StorageClass stc = 0);
const char *kind();
TypeFunction *copy();
Type *syntaxCopy();
Type *semantic(Loc loc, Scope *sc);
void purityLevel();
Expand Down
10 changes: 0 additions & 10 deletions test/fail_compilation/fail3866.d

This file was deleted.

Loading