mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-01-16 12:53:14 +01:00
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:
@@ -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, ¶meters, &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()
|
||||
{
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user