Merge DMD r303: harmonize

---
 dmd/expression.c |   78 ++++++++++++++++++++++++++++++++++++++++++++++++-----
 dmd/expression.h |    8 +++++
 dmd/template.c   |   27 ++++++++++++-------
 3 files changed, 95 insertions(+), 18 deletions(-)
This commit is contained in:
Leandro Lucarella
2010-01-06 15:18:21 -03:00
parent 072ac6c4e3
commit 6e61ecee6b
3 changed files with 95 additions and 18 deletions

View File

@@ -1187,6 +1187,10 @@ void Expression::checkEscape()
{
}
void Expression::checkEscapeRef()
{
}
void Expression::checkScalar()
{
if (!type->isscalar())
@@ -1203,7 +1207,7 @@ Expression *Expression::checkIntegral()
{
if (!type->isintegral())
{ error("'%s' is not of integral type, it is a %s", toChars(), type->toChars());
return new IntegerExp(0);
return new ErrorExp();
}
return this;
}
@@ -1212,7 +1216,7 @@ Expression *Expression::checkArithmetic()
{
if (!type->isintegral() && !type->isfloating())
{ error("'%s' is not of arithmetic type, it is a %s", toChars(), type->toChars());
return new IntegerExp(0);
return new ErrorExp();
}
return this;
}
@@ -3998,8 +4002,15 @@ void SymOffExp::checkEscape()
VarDeclaration *v = var->isVarDeclaration();
if (v)
{
if (!v->isDataseg())
error("escaping reference to local variable %s", v->toChars());
if (!v->isDataseg() && !(v->storage_class & (STCref | STCout)))
{ /* BUG: This should be allowed:
* void foo()
* { int a;
* int* bar() { return &a; }
* }
*/
error("escaping reference to local %s", v->toChars());
}
}
}
@@ -4049,6 +4060,7 @@ Expression *VarExp::semantic(Scope *sc)
}
#endif
}
/* Fix for 1161 doesn't work because it causes protection
* problems when instantiating imported templates passing private
* variables as alias template parameters.
@@ -4084,6 +4096,7 @@ Expression *VarExp::semantic(Scope *sc)
return e;
}
#endif
return this;
}
@@ -4113,6 +4126,16 @@ void VarExp::checkEscape()
}
}
void VarExp::checkEscapeRef()
{
VarDeclaration *v = var->isVarDeclaration();
if (v)
{
if (!v->isDataseg() && !(v->storage_class & (STCref | STCout)))
error("escaping reference to local variable %s", v->toChars());
}
}
#if DMDV2
int VarExp::isLvalue()
{
@@ -4744,6 +4767,12 @@ Expression *IsExp::semantic(Scope *sc)
goto Lno;
tded = targ;
break;
case TOKshared:
if (!targ->isShared())
goto Lno;
tded = targ;
break;
#endif
case TOKsuper:
@@ -4834,7 +4863,9 @@ Expression *IsExp::semantic(Scope *sc)
m = targ->deduceType(NULL, tspec, &parameters, &dedtypes);
if (m == MATCHnomatch ||
(m != MATCHexact && tok == TOKequal))
{
goto Lno;
}
else
{
assert(dedtypes.dim == 1);
@@ -4854,6 +4885,8 @@ Expression *IsExp::semantic(Scope *sc)
else if (tspec)
{
/* Evaluate to TRUE if targ matches tspec
* is(targ == tspec)
* is(targ : tspec)
*/
tspec = tspec->semantic(loc, sc);
//printf("targ = %s\n", targ->toChars());
@@ -5665,11 +5698,13 @@ Expression *DotIdExp::semantic(Scope *sc)
*/
unsigned errors = global.errors;
global.gag++;
Type *t1 = e1->type;
e = e1->type->dotExp(sc, e1, ident);
global.gag--;
if (errors != global.errors) // if failed to find the property
{
global.errors = errors;
e1->type = t1; // kludge to restore type
e = new DotIdExp(loc, new IdentifierExp(loc, Id::empty), ident);
e = new CallExp(loc, e, e1);
}
@@ -5863,7 +5898,7 @@ Expression *DotVarExp::modifiableLvalue(Scope *sc, Expression *e)
!var->type->isAssignable() ||
var->storage_class & STCmanifest
)
error("cannot modify const/invariant %s", toChars());
error("cannot modify const/immutable expression %s", toChars());
}
#endif
return this;
@@ -6940,6 +6975,11 @@ Expression *AddrExp::semantic(Scope *sc)
return this;
}
void AddrExp::checkEscape()
{
e1->checkEscapeRef();
}
/************************************************************/
PtrExp::PtrExp(Loc loc, Expression *e)
@@ -6995,6 +7035,11 @@ int PtrExp::isLvalue()
}
#endif
void PtrExp::checkEscapeRef()
{
e1->checkEscape();
}
Expression *PtrExp::toLvalue(Scope *sc, Expression *e)
{
#if 0
@@ -7572,7 +7617,9 @@ Expression *SliceExp::semantic(Scope *sc)
}
if (t->ty == Tarray)
{
type = e1->type;
}
else
type = t->nextOf()->arrayOf();
return e;
@@ -7584,7 +7631,7 @@ Lerror:
else
s = t->toChars();
error("%s cannot be sliced with []", s);
e = new IntegerExp(0);
e = new ErrorExp();
return e;
}
@@ -7593,6 +7640,11 @@ void SliceExp::checkEscape()
e1->checkEscape();
}
void SliceExp::checkEscapeRef()
{
e1->checkEscapeRef();
}
#if DMDV2
int SliceExp::isLvalue()
{
@@ -7638,8 +7690,7 @@ ArrayLengthExp::ArrayLengthExp(Loc loc, Expression *e1)
}
Expression *ArrayLengthExp::semantic(Scope *sc)
{ Expression *e;
{
#if LOGSEMANTIC
printf("ArrayLengthExp::semantic('%s')\n", toChars());
#endif
@@ -7792,6 +7843,11 @@ void CommaExp::checkEscape()
e2->checkEscape();
}
void CommaExp::checkEscapeRef()
{
e2->checkEscapeRef();
}
#if DMDV2
int CommaExp::isLvalue()
{
@@ -9971,6 +10027,12 @@ void CondExp::checkEscape()
e2->checkEscape();
}
void CondExp::checkEscapeRef()
{
e1->checkEscapeRef();
e2->checkEscapeRef();
}
Expression *CondExp::checkToBoolean()
{

View File

@@ -123,6 +123,7 @@ struct Expression : Object
virtual MATCH implicitConvTo(Type *t);
virtual Expression *castTo(Scope *sc, Type *t);
virtual void checkEscape();
virtual void checkEscapeRef();
void checkScalar();
void checkNoBool();
Expression *checkIntegral();
@@ -678,6 +679,8 @@ struct VarExp : Expression
char *toChars();
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
void checkEscape();
void checkEscapeRef();
int isLvalue();
Expression *toLvalue(Scope *sc, Expression *e);
Expression *modifiableLvalue(Scope *sc, Expression *e);
#if IN_DMD
@@ -1051,6 +1054,7 @@ struct AddrExp : UnaExp
AddrExp(Loc loc, Expression *e);
Expression *semantic(Scope *sc);
void checkEscape();
#if IN_DMD
elem *toElem(IRState *irs);
#endif
@@ -1069,6 +1073,7 @@ struct PtrExp : UnaExp
PtrExp(Loc loc, Expression *e);
PtrExp(Loc loc, Expression *e, Type *t);
Expression *semantic(Scope *sc);
void checkEscapeRef();
Expression *toLvalue(Scope *sc, Expression *e);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
#if IN_DMD
@@ -1221,6 +1226,7 @@ struct SliceExp : UnaExp
Expression *syntaxCopy();
Expression *semantic(Scope *sc);
void checkEscape();
void checkEscapeRef();
Expression *toLvalue(Scope *sc, Expression *e);
Expression *modifiableLvalue(Scope *sc, Expression *e);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
@@ -1294,6 +1300,7 @@ struct CommaExp : BinExp
CommaExp(Loc loc, Expression *e1, Expression *e2);
Expression *semantic(Scope *sc);
void checkEscape();
void checkEscapeRef();
Expression *toLvalue(Scope *sc, Expression *e);
Expression *modifiableLvalue(Scope *sc, Expression *e);
int isBool(int result);
@@ -1828,6 +1835,7 @@ struct CondExp : BinExp
Expression *optimize(int result);
Expression *interpret(InterState *istate);
void checkEscape();
void checkEscapeRef();
Expression *toLvalue(Scope *sc, Expression *e);
Expression *modifiableLvalue(Scope *sc, Expression *e);
Expression *checkToBoolean();

View File

@@ -762,7 +762,8 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(Loc loc, Objects *targsi,
int tuple_dim = 0;
MATCH match = MATCHexact;
FuncDeclaration *fd = onemember->toAlias()->isFuncDeclaration();
TypeFunction *fdtype; // type of fd
Parameters *fparameters; // function parameter list
int fvarargs; // function varargs
Objects dedtypes; // for T:T*, the dedargs is the T*, dedtypes is the T
#if 0
@@ -771,6 +772,8 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(Loc loc, Objects *targsi,
{ Expression *e = (Expression *)fargs->data[i];
printf("\tfarg[%d] is %s, type is %s\n", i, e->toChars(), e->type->toChars());
}
printf("fd = %s\n", fd->toChars());
printf("fd->type = %p\n", fd->type);
#endif
assert((size_t)scope > 0x10000);
@@ -849,10 +852,8 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(Loc loc, Objects *targsi,
}
#endif
assert(fd->type->ty == Tfunction);
fdtype = (TypeFunction *)fd->type;
nfparams = Parameter::dim(fdtype->parameters); // number of function parameters
fparameters = fd->getParameters(&fvarargs);
nfparams = Parameter::dim(fparameters); // number of function parameters
nfargs = fargs ? fargs->dim : 0; // number of function arguments
/* Check for match of function arguments with variadic template
@@ -882,14 +883,14 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(Loc loc, Objects *targsi,
*/
for (fptupindex = 0; fptupindex < nfparams; fptupindex++)
{
Parameter *fparam = (Parameter *)fdtype->parameters->data[fptupindex];
Parameter *fparam = (Parameter *)fparameters->data[fptupindex];
if (fparam->type->ty != Tident)
continue;
TypeIdentifier *tid = (TypeIdentifier *)fparam->type;
if (!tp->ident->equals(tid->ident) || tid->idents.dim)
continue;
if (fdtype->varargs) // variadic function doesn't
if (fvarargs) // variadic function doesn't
goto Lnomatch; // go with variadic template
/* The types of the function arguments
@@ -916,7 +917,7 @@ L1:
;
else if (nfargs > nfparams)
{
if (fdtype->varargs == 0)
if (fvarargs == 0)
goto Lnomatch; // too many args, no match
match = MATCHconvert; // match ... with a conversion
}
@@ -956,7 +957,7 @@ L2:
continue;
}
Parameter *fparam = Parameter::getNth(fdtype->parameters, i);
Parameter *fparam = Parameter::getNth(fparameters, i);
if (i >= nfargs) // if not enough arguments
{
@@ -1020,7 +1021,7 @@ L2:
/* The following code for variadic arguments closely
* matches TypeFunction::callMatch()
*/
if (!(fdtype->varargs == 2 && i + 1 == nfparams))
if (!(fvarargs == 2 && i + 1 == nfparams))
goto Lnomatch;
/* Check for match with function parameter T...
@@ -1132,6 +1133,7 @@ Lmatch:
if (constraint)
{ /* Check to see if constraint is satisfied.
*/
makeParamNamesVisibleInConstraint(paramscope);
Expression *e = constraint->syntaxCopy();
paramscope->flags |= SCOPEstaticif;
e = e->semantic(paramscope);
@@ -3262,7 +3264,10 @@ void TemplateInstance::semantic(Scope *sc)
// Nesting must match
if (isnested != ti->isnested)
{
//printf("test2 isnested %s ti->isnested %s\n", isnested ? isnested->toChars() : "", ti->isnested ? ti->isnested->toChars() : "");
continue;
}
#if 0
if (isnested && sc->parent != ti->parent)
continue;
@@ -3271,7 +3276,9 @@ void TemplateInstance::semantic(Scope *sc)
{ Object *o1 = (Object *)tdtypes.data[j];
Object *o2 = (Object *)ti->tdtypes.data[j];
if (!match(o1, o2, tempdecl, sc))
{
goto L1;
}
}
// It's a match