aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorIain Buclaw <ibuclaw@gcc.gnu.org>2018-12-17 18:32:31 +0000
committerIain Buclaw <ibuclaw@gcc.gnu.org>2018-12-17 18:32:31 +0000
commit4d814b69890171b7d742fabd966e5167b222cfd0 (patch)
treef23ff2741fedcf6d02736a2b3dc9e7ca2299f01c /gcc
parent22b04f05ab8e05707a031a5b6dfc1eb72d056957 (diff)
downloadgcc-4d814b69890171b7d742fabd966e5167b222cfd0.zip
gcc-4d814b69890171b7d742fabd966e5167b222cfd0.tar.gz
gcc-4d814b69890171b7d742fabd966e5167b222cfd0.tar.bz2
Merge dmd upstream 237ca3fbe
Backports a fix where a bad cast to TypeFunction resulted in memory corruption. The logic in the function semantic has been fixed, and casts have been replaced with a function call to always check the front-end AST node value. Reviewed-on: https://github.com/dlang/dmd/pull/9054 From-SVN: r267207
Diffstat (limited to 'gcc')
-rw-r--r--gcc/d/dmd/MERGE2
-rw-r--r--gcc/d/dmd/dclass.c8
-rw-r--r--gcc/d/dmd/dstruct.c3
-rw-r--r--gcc/d/dmd/func.c82
-rw-r--r--gcc/d/dmd/mtype.c16
-rw-r--r--gcc/d/dmd/mtype.h1
6 files changed, 59 insertions, 53 deletions
diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE
index a1a1fa0..bc35d4a 100644
--- a/gcc/d/dmd/MERGE
+++ b/gcc/d/dmd/MERGE
@@ -1,4 +1,4 @@
-e2fe2687b817a201528abaa3aa882333e04db01b
+237ca3fbe8f9ac4b64e26ce912c20439ee4fc63a
The first line of this file holds the git revision number of the last
merge done from the dlang/dmd repository.
diff --git a/gcc/d/dmd/dclass.c b/gcc/d/dmd/dclass.c
index 6fe17b3..ce9849f 100644
--- a/gcc/d/dmd/dclass.c
+++ b/gcc/d/dmd/dclass.c
@@ -805,7 +805,7 @@ Lancestorsdone:
if (fd && !fd->errors)
{
//printf("Creating default this(){} for class %s\n", toChars());
- TypeFunction *btf = (TypeFunction *)fd->type;
+ TypeFunction *btf = fd->type->toTypeFunction();
TypeFunction *tf = new TypeFunction(NULL, NULL, 0, LINKd, fd->storage_class);
tf->mod = btf->mod;
tf->purity = btf->purity;
@@ -1152,7 +1152,7 @@ int isf(void *param, Dsymbol *s)
bool ClassDeclaration::isFuncHidden(FuncDeclaration *fd)
{
- //printf("ClassDeclaration::isFuncHidden(class = %s, fd = %s)\n", toChars(), fd->toChars());
+ //printf("ClassDeclaration::isFuncHidden(class = %s, fd = %s)\n", toChars(), fd->toPrettyChars());
Dsymbol *s = search(Loc(), fd->ident, IgnoreAmbiguous | IgnoreErrors);
if (!s)
{
@@ -1749,6 +1749,7 @@ bool InterfaceDeclaration::isBaseOf(ClassDeclaration *cd, int *poffset)
//printf("\tX base %s\n", b->sym->toChars());
if (this == b->sym)
{
+ //printf("\tfound at offset %d\n", b->offset);
if (poffset)
{
// don't return incorrect offsets https://issues.dlang.org/show_bug.cgi?id=16980
@@ -1882,8 +1883,7 @@ bool BaseClass::fillVtbl(ClassDeclaration *cd, FuncDeclarations *vtbl, int newin
assert(ifd);
// Find corresponding function in this class
- tf = (ifd->type->ty == Tfunction) ? (TypeFunction *)(ifd->type) : NULL;
- assert(tf); // should always be non-null
+ tf = ifd->type->toTypeFunction();
fd = cd->findFunc(ifd->ident, tf);
if (fd && !fd->isAbstract())
{
diff --git a/gcc/d/dmd/dstruct.c b/gcc/d/dmd/dstruct.c
index f9f15ba..77d6174 100644
--- a/gcc/d/dmd/dstruct.c
+++ b/gcc/d/dmd/dstruct.c
@@ -46,7 +46,7 @@ FuncDeclaration *search_toString(StructDeclaration *sd)
if (!tftostring)
{
tftostring = new TypeFunction(NULL, Type::tstring, 0, LINKd);
- tftostring = (TypeFunction *)tftostring->merge();
+ tftostring = tftostring->merge()->toTypeFunction();
}
fd = fd->overloadExactMatch(tftostring);
@@ -92,6 +92,7 @@ void semanticTypeInfo(Scope *sc, Type *t)
}
void visit(TypeStruct *t)
{
+ //printf("semanticTypeInfo::visit(TypeStruct = %s)\n", t->toChars());
StructDeclaration *sd = t->sym;
/* Step 1: create TypeInfoDeclaration
diff --git a/gcc/d/dmd/func.c b/gcc/d/dmd/func.c
index c8f9c5c..4e1b3e2 100644
--- a/gcc/d/dmd/func.c
+++ b/gcc/d/dmd/func.c
@@ -411,8 +411,8 @@ static bool canInferAttributes(FuncDeclaration *fd, Scope *sc)
*/
static void initInferAttributes(FuncDeclaration *fd)
{
- assert(fd->type->ty == Tfunction);
- TypeFunction *tf = (TypeFunction *)fd->type;
+ //printf("initInferAttributes() for %s\n", toPrettyChars());
+ TypeFunction *tf = fd->type->toTypeFunction();
if (tf->purity == PUREimpure) // purity not specified
fd->flags |= FUNCFLAGpurityInprocess;
@@ -495,7 +495,7 @@ void FuncDeclaration::semantic(Scope *sc)
fld->tok = TOKfunction;
else
assert(0);
- linkage = ((TypeFunction *)treq->nextOf())->linkage;
+ linkage = treq->nextOf()->toTypeFunction()->linkage;
}
else
linkage = sc->linkage;
@@ -505,11 +505,21 @@ void FuncDeclaration::semantic(Scope *sc)
if (!originalType)
originalType = type->syntaxCopy();
+ if (type->ty != Tfunction)
+ {
+ if (type->ty != Terror)
+ {
+ error("%s must be a function instead of %s", toChars(), type->toChars());
+ type = Type::terror;
+ }
+ errors = true;
+ return;
+ }
if (!type->deco)
{
sc = sc->push();
sc->stc |= storage_class & (STCdisable | STCdeprecated); // forward to function type
- TypeFunction *tf = (TypeFunction *)type;
+ TypeFunction *tf = type->toTypeFunction();
if (sc->func)
{
@@ -678,8 +688,8 @@ void FuncDeclaration::semantic(Scope *sc)
{
// Merge back function attributes into 'originalType'.
// It's used for mangling, ddoc, and json output.
- TypeFunction *tfo = (TypeFunction *)originalType;
- TypeFunction *tfx = (TypeFunction *)type;
+ TypeFunction *tfo = originalType->toTypeFunction();
+ TypeFunction *tfx = type->toTypeFunction();
tfo->mod = tfx->mod;
tfo->isscope = tfx->isscope;
tfo->isscopeinferred = tfx->isscopeinferred;
@@ -1132,8 +1142,7 @@ void FuncDeclaration::semantic(Scope *sc)
error("override only applies to class member functions");
// Reflect this->type to f because it could be changed by findVtblIndex
- assert(type->ty == Tfunction);
- f = (TypeFunction *)type;
+ f = type->toTypeFunction();
/* Do not allow template instances to add virtual functions
* to a class.
@@ -2560,8 +2569,7 @@ void FuncDeclaration::buildResultVar(Scope *sc, Type *tret)
if (sc && vresult->semanticRun == PASSinit)
{
- assert(type->ty == Tfunction);
- TypeFunction *tf = (TypeFunction *)type;
+ TypeFunction *tf = type->toTypeFunction();
if (tf->isref)
vresult->storage_class |= STCref;
vresult->type = tret;
@@ -3135,7 +3143,7 @@ FuncDeclaration *FuncDeclaration::overloadModMatch(Loc loc, Type *tthis, bool &h
return 0;
m->anyf = f;
- TypeFunction *tf = (TypeFunction *)f->type;
+ TypeFunction *tf = f->type->toTypeFunction();
//printf("tf = %s\n", tf->toChars());
MATCH match;
@@ -3205,7 +3213,7 @@ FuncDeclaration *FuncDeclaration::overloadModMatch(Loc loc, Type *tthis, bool &h
else // no match
{
hasOverloads = true;
- TypeFunction *tf = (TypeFunction *)this->type;
+ TypeFunction *tf = this->type->toTypeFunction();
assert(tthis);
assert(!MODimplicitConv(tthis->mod, tf->mod)); // modifier mismatch
{
@@ -3270,8 +3278,8 @@ MATCH FuncDeclaration::leastAsSpecialized(FuncDeclaration *g)
* as g() is.
*/
- TypeFunction *tf = (TypeFunction *)type;
- TypeFunction *tg = (TypeFunction *)g->type;
+ TypeFunction *tf = type->toTypeFunction();
+ TypeFunction *tg = g->type->toTypeFunction();
size_t nfparams = Parameter::dim(tf->parameters);
/* If both functions have a 'this' pointer, and the mods are not
@@ -3524,7 +3532,7 @@ FuncDeclaration *resolveFuncCall(Loc loc, Scope *sc, Dsymbol *s,
assert(fd);
bool hasOverloads = fd->overnext != NULL;
- TypeFunction *tf = (TypeFunction *)fd->type;
+ TypeFunction *tf = fd->type->toTypeFunction();
if (tthis && !MODimplicitConv(tthis->mod, tf->mod)) // modifier mismatch
{
OutBuffer thisBuf, funcBuf;
@@ -3562,8 +3570,8 @@ FuncDeclaration *resolveFuncCall(Loc loc, Scope *sc, Dsymbol *s,
}
else if (m.nextf)
{
- TypeFunction *tf1 = (TypeFunction *)m.lastf->type;
- TypeFunction *tf2 = (TypeFunction *)m.nextf->type;
+ TypeFunction *tf1 = m.lastf->type->toTypeFunction();
+ TypeFunction *tf2 = m.nextf->type->toTypeFunction();
const char *lastprms = parametersTypeToChars(tf1->parameters, tf1->varargs);
const char *nextprms = parametersTypeToChars(tf2->parameters, tf2->varargs);
::error(loc, "%s.%s called with argument types %s matches both:\n"
@@ -3679,7 +3687,7 @@ const char *FuncDeclaration::toPrettyChars(bool QualifyTypes)
const char *FuncDeclaration::toFullSignature()
{
OutBuffer buf;
- functionToBufferWithIdent((TypeFunction *)type, &buf, toChars());
+ functionToBufferWithIdent(type->toTypeFunction(), &buf, toChars());
return buf.extractString();
}
@@ -3776,8 +3784,7 @@ bool FuncDeclaration::isOverloadable()
PURE FuncDeclaration::isPure()
{
//printf("FuncDeclaration::isPure() '%s'\n", toChars());
- assert(type->ty == Tfunction);
- TypeFunction *tf = (TypeFunction *)type;
+ TypeFunction *tf = type->toTypeFunction();
if (flags & FUNCFLAGpurityInprocess)
setImpure();
if (tf->purity == PUREfwdref)
@@ -3829,10 +3836,9 @@ bool FuncDeclaration::setImpure()
bool FuncDeclaration::isSafe()
{
- assert(type->ty == Tfunction);
if (flags & FUNCFLAGsafetyInprocess)
setUnsafe();
- return ((TypeFunction *)type)->trust == TRUSTsafe;
+ return type->toTypeFunction()->trust == TRUSTsafe;
}
bool FuncDeclaration::isSafeBypassingInference()
@@ -3842,10 +3848,9 @@ bool FuncDeclaration::isSafeBypassingInference()
bool FuncDeclaration::isTrusted()
{
- assert(type->ty == Tfunction);
if (flags & FUNCFLAGsafetyInprocess)
setUnsafe();
- return ((TypeFunction *)type)->trust == TRUSTtrusted;
+ return type->toTypeFunction()->trust == TRUSTtrusted;
}
/**************************************
@@ -3858,7 +3863,7 @@ bool FuncDeclaration::setUnsafe()
if (flags & FUNCFLAGsafetyInprocess)
{
flags &= ~FUNCFLAGsafetyInprocess;
- ((TypeFunction *)type)->trust = TRUSTsystem;
+ type->toTypeFunction()->trust = TRUSTsystem;
if (fes)
fes->func->setUnsafe();
}
@@ -3869,10 +3874,9 @@ bool FuncDeclaration::setUnsafe()
bool FuncDeclaration::isNogc()
{
- assert(type->ty == Tfunction);
if (flags & FUNCFLAGnogcInprocess)
setGC();
- return ((TypeFunction *)type)->isnogc;
+ return type->toTypeFunction()->isnogc;
}
bool FuncDeclaration::isNogcBypassingInference()
@@ -3891,7 +3895,7 @@ bool FuncDeclaration::setGC()
if (flags & FUNCFLAGnogcInprocess)
{
flags &= ~FUNCFLAGnogcInprocess;
- ((TypeFunction *)type)->isnogc = false;
+ type->toTypeFunction()->isnogc = false;
if (fes)
fes->func->setGC();
}
@@ -4000,8 +4004,7 @@ bool traverseIndirections(Type *ta, Type *tb, void *p = NULL, bool reversePass =
bool FuncDeclaration::isolateReturn()
{
- assert(type->ty == Tfunction);
- TypeFunction *tf = (TypeFunction *)type;
+ TypeFunction *tf = type->toTypeFunction();
assert(tf->next);
Type *treti = tf->next;
@@ -4022,8 +4025,7 @@ bool FuncDeclaration::parametersIntersect(Type *t)
if (!isPureBypassingInference() || isNested())
return false;
- assert(type->ty == Tfunction);
- TypeFunction *tf = (TypeFunction *)type;
+ TypeFunction *tf = type->toTypeFunction();
//printf("parametersIntersect(%s) t = %s\n", tf->toChars(), t->toChars());
@@ -4229,7 +4231,7 @@ FuncDeclaration *FuncDeclaration::genCfunc(Parameters *fparams, Type *treturn, I
*/
void FuncDeclaration::checkDmain()
{
- TypeFunction *tf = (TypeFunction *)type;
+ TypeFunction *tf = type->toTypeFunction();
const size_t nparams = Parameter::dim(tf->parameters);
bool argerr = false;
if (nparams == 1)
@@ -4608,8 +4610,7 @@ Parameters *FuncDeclaration::getParameters(int *pvarargs)
if (type)
{
- assert(type->ty == Tfunction);
- TypeFunction *fdtype = (TypeFunction *)type;
+ TypeFunction *fdtype = type->toTypeFunction();
fparameters = fdtype->parameters;
fvarargs = fdtype->varargs;
}
@@ -4752,7 +4753,7 @@ void FuncLiteralDeclaration::modifyReturns(Scope *sc, Type *tret)
// This is required so the code generator does not try to cast the
// modified returns back to the original type.
if (inferRetType && type->nextOf() != tret)
- ((TypeFunction *)type)->next = tret;
+ type->toTypeFunction()->next = tret;
}
const char *FuncLiteralDeclaration::kind() const
@@ -4820,8 +4821,7 @@ void CtorDeclaration::semantic(Scope *sc)
if (errors)
return;
- TypeFunction *tf = (TypeFunction *)type;
- assert(tf && tf->ty == Tfunction);
+ TypeFunction *tf = type->toTypeFunction();
/* See if it's the default constructor
* But, template constructor should not become a default constructor.
@@ -5502,10 +5502,9 @@ void NewDeclaration::semantic(Scope *sc)
type = new TypeFunction(parameters, tret, varargs, LINKd, storage_class);
type = type->semantic(loc, sc);
- assert(type->ty == Tfunction);
// Check that there is at least one argument of type size_t
- TypeFunction *tf = (TypeFunction *)type;
+ TypeFunction *tf = type->toTypeFunction();
if (Parameter::dim(tf->parameters) < 1)
{
error("at least one argument of type size_t expected");
@@ -5581,10 +5580,9 @@ void DeleteDeclaration::semantic(Scope *sc)
type = new TypeFunction(parameters, Type::tvoid, 0, LINKd, storage_class);
type = type->semantic(loc, sc);
- assert(type->ty == Tfunction);
// Check that there is only one argument of type void*
- TypeFunction *tf = (TypeFunction *)type;
+ TypeFunction *tf = type->toTypeFunction();
if (Parameter::dim(tf->parameters) != 1)
{
error("one argument of type void* expected");
diff --git a/gcc/d/dmd/mtype.c b/gcc/d/dmd/mtype.c
index b35b7af..5259803 100644
--- a/gcc/d/dmd/mtype.c
+++ b/gcc/d/dmd/mtype.c
@@ -2345,6 +2345,12 @@ TypeBasic *Type::isTypeBasic()
return NULL;
}
+TypeFunction *Type::toTypeFunction()
+{
+ if (ty != Tfunction)
+ assert(0);
+ return (TypeFunction *)this;
+}
/***************************************
* Resolve 'this' type to either type, symbol, or expression.
@@ -4808,14 +4814,14 @@ Expression *TypeAArray::dotExp(Scope *sc, Expression *e, Identifier *ident, int
Parameters *fparams = new Parameters();
fparams->push(new Parameter(STCin, this, NULL, NULL));
fd_aaLen = FuncDeclaration::genCfunc(fparams, Type::tsize_t, Id::aaLen);
- TypeFunction *tf = (TypeFunction *)fd_aaLen->type;
+ TypeFunction *tf = fd_aaLen->type->toTypeFunction();
tf->purity = PUREconst;
tf->isnothrow = true;
tf->isnogc = false;
}
Expression *ev = new VarExp(e->loc, fd_aaLen, false);
e = new CallExp(e->loc, ev, e);
- e->type = ((TypeFunction *)fd_aaLen->type)->next;
+ e->type = fd_aaLen->type->toTypeFunction()->next;
}
else
e = Type::dotExp(sc, e, ident, flag);
@@ -5425,7 +5431,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 = (TypeFunction *)copy();
+ TypeFunction *tf = copy()->toTypeFunction();
if (parameters)
{
tf->parameters = parameters->copy();
@@ -6283,7 +6289,7 @@ Expression *TypeFunction::defaultInit(Loc loc)
Type *TypeFunction::addStorageClass(StorageClass stc)
{
//printf("addStorageClass(%llx) %d\n", stc, (stc & STCscope) != 0);
- TypeFunction *t = (TypeFunction *)Type::addStorageClass(stc);
+ TypeFunction *t = Type::addStorageClass(stc)->toTypeFunction();
if ((stc & STCpure && !t->purity) ||
(stc & STCnothrow && !t->isnothrow) ||
(stc & STCnogc && !t->isnogc) ||
@@ -9181,7 +9187,7 @@ Type *Parameter::isLazyArray()
if (tel->ty == Tdelegate)
{
TypeDelegate *td = (TypeDelegate *)tel;
- TypeFunction *tf = (TypeFunction *)td->next;
+ TypeFunction *tf = td->next->toTypeFunction();
if (!tf->varargs && Parameter::dim(tf->parameters) == 0)
{
diff --git a/gcc/d/dmd/mtype.h b/gcc/d/dmd/mtype.h
index c3b8a97..b459fdf 100644
--- a/gcc/d/dmd/mtype.h
+++ b/gcc/d/dmd/mtype.h
@@ -335,6 +335,7 @@ public:
virtual bool needsDestruction();
virtual bool needsNested();
void checkComplexTransition(Loc loc);
+ TypeFunction *toTypeFunction();
static void error(Loc loc, const char *format, ...);
static void warning(Loc loc, const char *format, ...);