Merged the last bits of dmdfe 2.059

This commit is contained in:
Alexey Prokhin
2012-04-22 09:43:53 +04:00
17 changed files with 296 additions and 56 deletions

View File

@@ -56,7 +56,7 @@ Dsymbols *AttribDeclaration::include(Scope *sc, ScopeDsymbol *sd)
int AttribDeclaration::apply(Dsymbol_apply_ft_t fp, void *param)
{
Dsymbols *d = include(NULL, NULL);
Dsymbols *d = include(scope, NULL);
if (d)
{
@@ -1278,9 +1278,9 @@ void ConditionalDeclaration::emitComment(Scope *sc)
Dsymbols *ConditionalDeclaration::include(Scope *sc, ScopeDsymbol *sd)
{
//printf("ConditionalDeclaration::include()\n");
//printf("ConditionalDeclaration::include(sc = %p) scope = %p\n", sc, scope);
assert(condition);
return condition->include(sc, sd) ? decl : elsedecl;
return condition->include(scope ? scope : sc, sd) ? decl : elsedecl;
}
void ConditionalDeclaration::setScope(Scope *sc)
@@ -1440,6 +1440,9 @@ void StaticIfDeclaration::importAll(Scope *sc)
void StaticIfDeclaration::setScope(Scope *sc)
{
// do not evaluate condition before semantic pass
// But do set the scope, in case we need it for forward referencing
Dsymbol::setScope(sc);
}
void StaticIfDeclaration::semantic(Scope *sc)
@@ -1471,6 +1474,8 @@ const char *StaticIfDeclaration::kind()
/***************************** CompileDeclaration *****************************/
// These are mixin declarations, like mixin("int x");
CompileDeclaration::CompileDeclaration(Loc loc, Expression *exp)
: AttribDeclaration(NULL)
{
@@ -1544,3 +1549,10 @@ void CompileDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
buf->writestring(");");
buf->writenl();
}
const char *CompileDeclaration::kind()
{
return "mixin";
}

View File

@@ -200,6 +200,7 @@ struct CompileDeclaration : AttribDeclaration
void compileIt(Scope *sc);
void semantic(Scope *sc);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
const char *kind();
};
#endif /* DMD_ATTRIB_H */

View File

@@ -1,6 +1,6 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2011 by Digital Mars
// Copyright (c) 1999-2012 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@@ -22,6 +22,7 @@
#include "lexer.h"
#include "mtype.h"
#include "scope.h"
#include "arraytypes.h"
int findCondition(Strings *ids, Identifier *ident)
{
@@ -29,7 +30,7 @@ int findCondition(Strings *ids, Identifier *ident)
{
for (size_t i = 0; i < ids->dim; i++)
{
const char *id = ids->tdata()[i];
const char *id = (*ids)[i];
if (strcmp(id, ident->toChars()) == 0)
return TRUE;
@@ -224,6 +225,7 @@ StaticIfCondition::StaticIfCondition(Loc loc, Expression *exp)
: Condition(loc)
{
this->exp = exp;
this->nest = 0;
}
Condition *StaticIfCondition::syntaxCopy()
@@ -234,7 +236,7 @@ Condition *StaticIfCondition::syntaxCopy()
int StaticIfCondition::include(Scope *sc, ScopeDsymbol *s)
{
#if 0
printf("StaticIfCondition::include(sc = %p, s = %p)\n", sc, s);
printf("StaticIfCondition::include(sc = %p, s = %p) this=%p inc = %d\n", sc, s, this, inc);
if (s)
{
printf("\ts = '%s', kind = %s\n", s->toChars(), s->kind());
@@ -242,6 +244,15 @@ int StaticIfCondition::include(Scope *sc, ScopeDsymbol *s)
#endif
if (inc == 0)
{
if (exp->op == TOKerror || nest > 100)
{
error(loc, (nest > 1000) ? "unresolvable circular static if expression"
: "error evaluating static if expression");
if (!global.gag)
inc = 2; // so we don't see the error message again
return 0;
}
if (!sc)
{
error(loc, "static if conditional cannot be at global scope");
@@ -249,13 +260,19 @@ int StaticIfCondition::include(Scope *sc, ScopeDsymbol *s)
return 0;
}
++nest;
sc = sc->push(sc->scopesym);
sc->sd = s; // s gets any addMember()
sc->flags |= SCOPEstaticif;
Expression *e = exp->semantic(sc);
sc->pop();
e = e->optimize(WANTvalue | WANTinterpret);
if (e->isBool(TRUE))
--nest;
if (e->op == TOKerror)
{ exp = e;
inc = 0;
}
else if (e->isBool(TRUE))
inc = 1;
else if (e->isBool(FALSE))
inc = 2;
@@ -327,7 +344,7 @@ int IftypeCondition::include(Scope *sc, ScopeDsymbol *sd)
TemplateParameters parameters;
parameters.setDim(1);
parameters.tdata()[0] = &tp;
parameters[0] = &tp;
Objects dedtypes;
dedtypes.setDim(1);
@@ -339,7 +356,7 @@ int IftypeCondition::include(Scope *sc, ScopeDsymbol *sd)
else
{
inc = 1;
Type *tded = (Type *)dedtypes.tdata()[0];
Type *tded = (Type *)dedtypes[0];
if (!tded)
tded = targ;
Dsymbol *s = new AliasDeclaration(loc, id, tded);

View File

@@ -1,6 +1,6 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2011 by Digital Mars
// Copyright (c) 1999-2012 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@@ -79,6 +79,7 @@ struct VersionCondition : DVCondition
struct StaticIfCondition : Condition
{
Expression *exp;
int nest; // limit circular dependencies
StaticIfCondition(Loc loc, Expression *exp);
Condition *syntaxCopy();

View File

@@ -796,6 +796,7 @@ void VarDeclaration::semantic(Scope *sc)
if (!type)
{ inuse++;
//printf("inferring type for %s with init %s\n", toChars(), init->toChars());
ArrayInitializer *ai = init->isArrayInitializer();
if (ai)
{ Expression *e;
@@ -816,7 +817,6 @@ void VarDeclaration::semantic(Scope *sc)
else
type = init->inferType(sc);
//printf("test2: %s, %s, %s\n", toChars(), type->toChars(), type->deco);
// type = type->semantic(loc, sc);
inuse--;
@@ -883,7 +883,14 @@ void VarDeclaration::semantic(Scope *sc)
Type *tb = type->toBasetype();
if (tb->ty == Tvoid && !(storage_class & STClazy))
{ error("voids have no value");
{
if (inferred)
{
error("type %s is inferred from initializer %s, and variables cannot be of type void",
type->toChars(), init->toChars());
}
else
error("variables cannot be of type void");
type = Type::terror;
tb = type;
}

View File

@@ -338,7 +338,15 @@ void checkPropertyCall(Expression *e, Expression *emsg)
{ CallExp *ce = (CallExp *)e;
TypeFunction *tf;
if (ce->f)
{
tf = (TypeFunction *)ce->f->type;
/* If a forward reference to ce->f, try to resolve it
*/
if (!tf->deco && ce->f->scope)
{ ce->f->semantic(ce->f->scope);
tf = (TypeFunction *)ce->f->type;
}
}
else if (ce->e1->type->ty == Tfunction)
tf = (TypeFunction *)ce->e1->type;
else if (ce->e1->type->ty == Tdelegate)
@@ -390,46 +398,54 @@ Expression *resolveUFCSProperties(Scope *sc, Expression *e1, Expression *e2 = NU
else
e = new DotIdExp(loc, e, ident);
Expressions *arguments = new Expressions();
/* .f(e1, e2)
*/
if (e2)
{
arguments->setDim(2);
(*arguments)[0] = eleft;
(*arguments)[1] = e2;
/* .f(e1) = e2
*/
Expression *ex = e->syntaxCopy();
e = new CallExp(loc, e, arguments);
e = e->trySemantic(sc);
if (e)
{ checkPropertyCall(e, e1);
return e->semantic(sc);
}
e = ex;
}
Expressions *a1 = new Expressions();
a1->setDim(1);
(*a1)[0] = eleft;
ex = new CallExp(loc, ex, a1);
ex = ex->trySemantic(sc);
/* .f(e1)
* .f(e1) = e2
*/
/* .f(e1, e2)
*/
Expressions *a2 = new Expressions();
a2->setDim(2);
(*a2)[0] = eleft;
(*a2)[1] = e2;
e = new CallExp(loc, e, a2);
if (ex)
{ // if fallback setter exists, gag errors
e = e->trySemantic(sc);
if (!e)
{ checkPropertyCall(ex, e1);
ex = new AssignExp(loc, ex, e2);
return ex->semantic(sc);
}
}
else
{ // strict setter prints errors if fails
e = e->semantic(sc);
}
checkPropertyCall(e, e1);
return e;
}
else
{
/* .f(e1)
*/
Expressions *arguments = new Expressions();
arguments->setDim(1);
(*arguments)[0] = eleft;
e = new CallExp(loc, e, arguments);
e = e->trySemantic(sc);
if (!e)
goto Leprop;
e = e->semantic(sc);
checkPropertyCall(e, e1);
if (e2)
e = new AssignExp(loc, e, e2);
return e->semantic(sc);
}
}
return e;
Leprop:
e1->error("not a property %s", e1->toChars());
return new ErrorExp();
}
/******************************
@@ -1045,7 +1061,37 @@ Type *functionParameters(Loc loc, Scope *sc, TypeFunction *tf,
}
if (p->storageClass & STCref)
{
arg = arg->toLvalue(sc, arg);
if (arg->op == TOKstructliteral)
{
Identifier *idtmp = Lexer::uniqueId("__tmpsl");
VarDeclaration *tmp = new VarDeclaration(loc, arg->type, idtmp, new ExpInitializer(0, arg));
tmp->storage_class |= STCctfe;
Expression *ae = new DeclarationExp(loc, tmp);
Expression *e = new CommaExp(loc, ae, new VarExp(loc, tmp));
e = e->semantic(sc);
arg = e;
}
else if (arg->op == TOKcall)
{
CallExp *ce = (CallExp *)arg;
if (ce->e1->op == TOKdotvar &&
((DotVarExp *)ce->e1)->var->isCtorDeclaration())
{
DotVarExp *dve = (DotVarExp *)ce->e1;
assert(dve->e1->op == TOKcomma);
assert(((CommaExp *)dve->e1)->e2->op == TOKvar);
VarExp *ve = (VarExp *)((CommaExp *)dve->e1)->e2;
VarDeclaration *tmp = ve->var->isVarDeclaration();
arg = new CommaExp(arg->loc, arg, new VarExp(loc, tmp));
arg = arg->semantic(sc);
}
else
arg = arg->toLvalue(sc, arg);
}
else
arg = arg->toLvalue(sc, arg);
}
else if (p->storageClass & STCout)
{
@@ -6753,9 +6799,29 @@ Expression *DotIdExp::semantic(Scope *sc, int flag)
{ goto L2;
}
unsigned errors = global.startGagging();
/* This would be much better if we added a "hasProperty" method to types,
* i.e. the gagging is a bad way.
*/
if (t1b->ty == Taarray)
{
TypeAArray *taa = (TypeAArray *)t1b;
if (!taa->impl &&
ident != Id::__sizeof &&
ident != Id::__xalignof &&
ident != Id::init &&
ident != Id::mangleof &&
ident != Id::stringof &&
ident != Id::offsetof)
{
// Find out about these errors when not gagged
taa->getImpl();
}
}
Type *t1 = e1->type;
e = e1->type->dotExp(sc, e1, ident);
unsigned errors = global.startGagging();
e = t1->dotExp(sc, e1, ident);
if (global.endGagging(errors)) // if failed to find the property
{
e1->type = t1; // kludge to restore type
@@ -8841,6 +8907,8 @@ Expression *CastExp::semantic(Scope *sc)
}
else
to = to->semantic(loc, sc);
if (to == Type::terror)
return new ErrorExp();
if (!to->equals(e1->type))
{
@@ -9091,7 +9159,9 @@ Expression *SliceExp::syntaxCopy()
if (this->upr)
upr = this->upr->syntaxCopy();
return new SliceExp(loc, e1->syntaxCopy(), lwr, upr);
SliceExp *se = new SliceExp(loc, e1->syntaxCopy(), lwr, upr);
se->lengthVar = this->lengthVar; // bug7871
return se;
}
Expression *SliceExp::semantic(Scope *sc)
@@ -9436,7 +9506,9 @@ ArrayExp::ArrayExp(Loc loc, Expression *e1, Expressions *args)
Expression *ArrayExp::syntaxCopy()
{
return new ArrayExp(loc, e1->syntaxCopy(), arraySyntaxCopy(arguments));
ArrayExp *ae = new ArrayExp(loc, e1->syntaxCopy(), arraySyntaxCopy(arguments));
ae->lengthVar = this->lengthVar; // bug7871
return ae;
}
Expression *ArrayExp::semantic(Scope *sc)
@@ -9603,6 +9675,13 @@ IndexExp::IndexExp(Loc loc, Expression *e1, Expression *e2)
modifiable = 0; // assume it is an rvalue
}
Expression *IndexExp::syntaxCopy()
{
IndexExp *ie = new IndexExp(loc, e1->syntaxCopy(), e2->syntaxCopy());
ie->lengthVar = this->lengthVar; // bug7871
return ie;
}
Expression *IndexExp::semantic(Scope *sc)
{ Expression *e;
Type *t1;

View File

@@ -1,6 +1,6 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2011 by Digital Mars
// Copyright (c) 1999-2012 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@@ -1463,6 +1463,7 @@ struct IndexExp : BinExp
int modifiable;
IndexExp(Loc loc, Expression *e1, Expression *e2);
Expression *syntaxCopy();
Expression *semantic(Scope *sc);
int isLvalue();
Expression *toLvalue(Scope *sc, Expression *e);

View File

@@ -190,6 +190,11 @@ void FuncDeclaration::semantic(Scope *sc)
semanticRun = PASSsemantic;
}
if (scope)
{ sc = scope;
scope = NULL;
}
unsigned dprogress_save = Module::dprogress;
foverrides.setDim(0); // reset in case semantic() is being retried for this function
@@ -2895,6 +2900,9 @@ int FuncDeclaration::isImportedSymbol()
int FuncDeclaration::isVirtual()
{
if (toAliasFunc() != this)
return toAliasFunc()->isVirtual();
Dsymbol *p = toParent();
#if 0
printf("FuncDeclaration::isVirtual(%s)\n", toChars());
@@ -2915,6 +2923,9 @@ int FuncDeclaration::isVirtual()
int FuncDeclaration::isVirtualMethod()
{
if (toAliasFunc() != this)
return toAliasFunc()->isVirtualMethod();
//printf("FuncDeclaration::isVirtualMethod() %s\n", toChars());
if (!isVirtual())
return 0;
@@ -2928,6 +2939,9 @@ int FuncDeclaration::isVirtualMethod()
int FuncDeclaration::isFinal()
{
if (toAliasFunc() != this)
return toAliasFunc()->isFinal();
ClassDeclaration *cd;
#if 0
printf("FuncDeclaration::isFinal(%s), %x\n", toChars(), Declaration::isFinal());
@@ -3444,6 +3458,11 @@ void CtorDeclaration::semantic(Scope *sc)
TypeFunction *tf = (TypeFunction *)type;
assert(tf && tf->ty == Tfunction);
if (scope)
{ sc = scope;
scope = NULL;
}
sc = sc->push();
sc->stc &= ~STCstatic; // not a static constructor
sc->flags |= SCOPEctor;
@@ -3563,6 +3582,10 @@ void PostBlitDeclaration::semantic(Scope *sc)
//printf("PostBlitDeclaration::semantic() %s\n", toChars());
//printf("ident: %s, %s, %p, %p\n", ident->toChars(), Id::dtor->toChars(), ident, Id::dtor);
//printf("stc = x%llx\n", sc->stc);
if (scope)
{ sc = scope;
scope = NULL;
}
parent = sc->parent;
Dsymbol *parent = toParent();
StructDeclaration *ad = parent->isStructDeclaration();
@@ -3636,6 +3659,10 @@ void DtorDeclaration::semantic(Scope *sc)
{
//printf("DtorDeclaration::semantic() %s\n", toChars());
//printf("ident: %s, %s, %p, %p\n", ident->toChars(), Id::dtor->toChars(), ident, Id::dtor);
if (scope)
{ sc = scope;
scope = NULL;
}
parent = sc->parent;
Dsymbol *parent = toParent();
AggregateDeclaration *ad = parent->isAggregateDeclaration();
@@ -3728,6 +3755,11 @@ void StaticCtorDeclaration::semantic(Scope *sc)
{
//printf("StaticCtorDeclaration::semantic()\n");
if (scope)
{ sc = scope;
scope = NULL;
}
if (!type)
type = new TypeFunction(NULL, Type::tvoid, FALSE, LINKd);
@@ -3856,6 +3888,11 @@ Dsymbol *StaticDtorDeclaration::syntaxCopy(Dsymbol *s)
void StaticDtorDeclaration::semantic(Scope *sc)
{
if (scope)
{ sc = scope;
scope = NULL;
}
ClassDeclaration *cd = sc->scopesym->isClassDeclaration();
if (!type)
@@ -3983,6 +4020,10 @@ Dsymbol *InvariantDeclaration::syntaxCopy(Dsymbol *s)
void InvariantDeclaration::semantic(Scope *sc)
{
if (scope)
{ sc = scope;
scope = NULL;
}
parent = sc->parent;
Dsymbol *parent = toParent();
AggregateDeclaration *ad = parent->isAggregateDeclaration();
@@ -4063,6 +4104,10 @@ Dsymbol *UnitTestDeclaration::syntaxCopy(Dsymbol *s)
void UnitTestDeclaration::semantic(Scope *sc)
{
if (scope)
{ sc = scope;
scope = NULL;
}
#if IN_LLVM
if (global.params.useUnitTests && sc->module->isRoot)
#else
@@ -4150,6 +4195,11 @@ void NewDeclaration::semantic(Scope *sc)
{
//printf("NewDeclaration::semantic()\n");
if (scope)
{ sc = scope;
scope = NULL;
}
parent = sc->parent;
Dsymbol *parent = toParent();
ClassDeclaration *cd = parent->isClassDeclaration();
@@ -4234,6 +4284,11 @@ void DeleteDeclaration::semantic(Scope *sc)
{
//printf("DeleteDeclaration::semantic()\n");
if (scope)
{ sc = scope;
scope = NULL;
}
parent = sc->parent;
Dsymbol *parent = toParent();
ClassDeclaration *cd = parent->isClassDeclaration();

View File

@@ -21,6 +21,7 @@
#include "scope.h"
#include "mtype.h"
#include "hdrgen.h"
#include "template.h"
/********************************** Initializer *******************************/
@@ -160,8 +161,18 @@ Initializer *StructInitializer::semantic(Scope *sc, Type *t, int needInterpret)
if (ad->ctor)
error(loc, "%s %s has constructors, cannot use { initializers }, use %s( initializers ) instead",
ad->kind(), ad->toChars(), ad->toChars());
size_t nfields = ad->fields.dim;
if (((StructDeclaration *)ad)->isnested) nfields--;
StructDeclaration *sd = ad->isStructDeclaration();
assert(sd);
sd->size(loc);
if (sd->sizeok != SIZEOKdone)
{
error(loc, "struct %s is forward referenced", sd->toChars());
errors = 1;
goto Lerror;
}
size_t nfields = sd->fields.dim;
if (sd->isnested)
nfields--;
for (size_t i = 0; i < field.dim; i++)
{
Identifier *id = field[i];
@@ -244,6 +255,7 @@ Initializer *StructInitializer::semantic(Scope *sc, Type *t, int needInterpret)
error(loc, "a struct is not a valid initializer for a %s", t->toChars());
errors = 1;
}
Lerror:
if (errors)
{
field.setDim(0);
@@ -264,12 +276,11 @@ Expression *StructInitializer::toExpression()
//printf("StructInitializer::toExpression() %s\n", toChars());
if (!ad) // if fwd referenced
{
return NULL;
}
StructDeclaration *sd = ad->isStructDeclaration();
if (!sd)
return NULL;
Expressions *elements = new Expressions();
size_t nfields = ad->fields.dim;
#if DMDV2
@@ -870,6 +881,15 @@ Type *ExpInitializer::inferType(Scope *sc)
//printf("ExpInitializer::inferType() %s\n", toChars());
exp = exp->semantic(sc);
exp = resolveProperties(sc, exp);
if (exp->op == TOKimport)
{ ScopeExp *se = (ScopeExp *)exp;
TemplateInstance *ti = se->sds->isTemplateInstance();
if (ti && ti->semanticRun == PASSsemantic && !ti->aliasdecl)
se->error("cannot infer type from %s %s, possible circular dependency", se->sds->kind(), se->toChars());
else
se->error("cannot infer type from %s %s", se->sds->kind(), se->toChars());
return Type::terror;
}
// Give error for overloaded function addresses
if (exp->op == TOKsymoff)

View File

@@ -6786,7 +6786,8 @@ Expression *TypeStruct::voidInitLiteral(VarDeclaration *var)
exps->setDim(sym->fields.dim);
for (size_t i = 0; i < sym->fields.dim; i++)
{
(*exps)[i] = new VoidInitExp(var, sym->fields[i]->type);
//(*exps)[i] = new VoidInitExp(var, sym->fields[i]->type);
(*exps)[i] = sym->fields[i]->type->voidInitLiteral(var);
}
StructLiteralExp *se = new StructLiteralExp(var->loc, sym, exps);
se->type = this;

View File

@@ -1000,6 +1000,8 @@ void Module::semantic2(Scope* unused_sc)
return;
}
//printf("Module::semantic2('%s'): parent = %p\n", toChars(), parent);
if (semanticRun == 0) // semantic() not completed yet - could be recursive call
return;
if (semanticstarted >= 2)
return;
assert(semanticstarted == 1);

View File

@@ -6066,6 +6066,19 @@ int TypeFunction::callMatch(Expression *ethis, Expressions *args, int flag)
new IntegerExp(0, ((StringExp *)arg)->len,
Type::tindex));
}
else if (arg->op == TOKstructliteral)
match = MATCHconvert;
else if (arg->op == TOKcall)
{
CallExp *ce = (CallExp *)arg;
if (ce->e1->op == TOKdotvar &&
((DotVarExp *)ce->e1)->var->isCtorDeclaration())
{
match = MATCHconvert;
}
else
goto Nomatch;
}
else
goto Nomatch;
}
@@ -7933,7 +7946,15 @@ Expression *TypeStruct::dotExp(Scope *sc, Expression *e, Identifier *ident)
L1:
if (!s)
{
return noMember(sc, e, ident);
if (sym->scope) // it's a fwd ref, maybe we can resolve it
{
sym->semantic(NULL);
s = sym->search(e->loc, ident, 0);
if (!s)
return noMember(sc, e, ident);
}
else
return noMember(sc, e, ident);
}
if (!s->isFuncDeclaration()) // because of overloading
s->checkDeprecated(e->loc, sc);

View File

@@ -465,7 +465,7 @@ void StructDeclaration::semantic(Scope *sc)
*/
//if (s->isEnumDeclaration() || (s->isAggregateDeclaration() && s->ident))
{
//printf("setScope %s %s\n", s->kind(), s->toChars());
//printf("struct: setScope %s %s\n", s->kind(), s->toChars());
s->setScope(sc2);
}
}
@@ -487,7 +487,9 @@ void StructDeclaration::semantic(Scope *sc)
// Ungag errors when not speculative
unsigned oldgag = global.gag;
if (global.isSpeculativeGagging() && !isSpeculative())
{
global.gag = 0;
}
s->semantic(sc2);
global.gag = oldgag;
}

View File

@@ -1510,7 +1510,23 @@ Lretry:
if (m && (fparam->storageClass & (STCref | STCauto)) == STCref)
{ if (!farg->isLvalue())
goto Lnomatch;
{
if (farg->op == TOKstructliteral)
m = MATCHconvert;
else if (farg->op == TOKcall)
{
CallExp *ce = (CallExp *)farg;
if (ce->e1->op == TOKdotvar &&
((DotVarExp *)ce->e1)->var->isCtorDeclaration())
{
m = MATCHconvert;
}
else
goto Lnomatch;
}
else
goto Lnomatch;
}
}
if (m && (fparam->storageClass & STCout))
{ if (!farg->isLvalue())
@@ -2326,7 +2342,7 @@ MATCH Type::deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters,
*wildmatch |= MODmutable;
else
*wildmatch |= (mod & ~MODshared);
tt = mutableOf();
tt = mutableOf()->substWildTo(MODmutable);
dedtypes->tdata()[i] = tt;
goto Lconst;
}

View File

@@ -528,6 +528,11 @@ Expression *TraitsExp::semantic(Scope *sc)
s1 = s1->toAlias();
s2 = s2->toAlias();
if (s1->isFuncAliasDeclaration())
s1 = ((FuncAliasDeclaration *)s1)->toAliasFunc();
if (s2->isFuncAliasDeclaration())
s2 = ((FuncAliasDeclaration *)s2)->toAliasFunc();
if (s1 == s2)
goto Ltrue;
else