Skip to content

Commit

Permalink
Fix breaking of compilable/test14838.d
Browse files Browse the repository at this point in the history
Add STCinference for attribute inference of opAssign/postblit/destructor.
  • Loading branch information
9rnsr committed Sep 14, 2015
1 parent 8e46763 commit 664b202
Show file tree
Hide file tree
Showing 7 changed files with 41 additions and 13 deletions.
1 change: 0 additions & 1 deletion src/aggregate.h
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,6 @@ class StructDeclaration : public AggregateDeclaration
bool hasIdentityEquals; // true if has identity opEquals
FuncDeclarations postblits; // Array of postblit functions
FuncDeclaration *postblit; // aggregate postblit
FuncDeclaration *fdassign; // generated opAssign function

FuncDeclaration *xeq; // TypeInfo_Struct.xopEquals
FuncDeclaration *xcmp; // TypeInfo_Struct.xopCmp
Expand Down
26 changes: 26 additions & 0 deletions src/class.c
Original file line number Diff line number Diff line change
Expand Up @@ -743,6 +743,32 @@ void ClassDeclaration::semantic(Scope *sc)
//printf("-ClassDeclaration::semantic(%s), type = %p\n", toChars(), type);
//members->print();

#if 0 // FIXME
LafterSizeok:
// The additions of special member functions should have its own
// sub-semantic analysis pass, and have to be deferred sometimes.
// See the case in compilable/test14838.d
for (size_t i = 0; i < fields.dim; i++)
{
VarDeclaration *v = fields[i];
Type *tb = v->type->baseElemOf();
if (tb->ty != Tstruct)
continue;
StructDeclaration *sd = ((TypeStruct *)tb)->sym;
if (sd->semanticRun >= PASSsemanticdone)
continue;

sc2->pop();

scope = scx ? scx : sc->copy();
scope->setNoFree();
scope->module->addDeferredSemantic(this);

//printf("\tdeferring %s\n", toChars());
return;
}
#endif

/* Look for special member functions.
* They must be in this class, not in a base class.
*/
Expand Down
10 changes: 9 additions & 1 deletion src/clone.c
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,7 @@ FuncDeclaration *buildOpAssign(StructDeclaration *sd, Scope *sc)
TypeFunction *tf = new TypeFunction(fparams, sd->handleType(), 0, LINKd, stc | STCref);

FuncDeclaration *fop = new FuncDeclaration(declLoc, Loc(), Id::assign, stc, tf);
fop->storage_class |= STCinference;

Expression *e = NULL;
if (stc & STCdisable)
Expand Down Expand Up @@ -302,7 +303,6 @@ FuncDeclaration *buildOpAssign(StructDeclaration *sd, Scope *sc)
sd->members->push(fop);
fop->addMember(sc, sd);
sd->hasIdentityAssign = true; // temporary mark identity assignable
sd->fdassign = fop;

unsigned errors = global.startGagging(); // Do not report errors, even if the
Scope *sc2 = sc->push();
Expand Down Expand Up @@ -800,6 +800,7 @@ FuncDeclaration *buildPostBlit(StructDeclaration *sd, Scope *sc)
StructDeclaration *sdv = ((TypeStruct *)tv)->sym;
if (!sdv->postblit)
continue;
sdv->postblit->functionSemantic();

stc = mergeFuncAttrs(stc, sdv->postblit);
stc = mergeFuncAttrs(stc, sdv->dtor);
Expand Down Expand Up @@ -853,6 +854,8 @@ FuncDeclaration *buildPostBlit(StructDeclaration *sd, Scope *sc)
*/
if (!sdv->dtor)
continue;
sdv->dtor->functionSemantic();

ex = new ThisExp(loc);
ex = new DotVarExp(loc, ex, v, 0);
if (v->type->toBasetype()->ty == Tstruct)
Expand Down Expand Up @@ -897,6 +900,7 @@ FuncDeclaration *buildPostBlit(StructDeclaration *sd, Scope *sc)
{
//printf("Building __fieldPostBlit()\n");
PostBlitDeclaration *dd = new PostBlitDeclaration(declLoc, Loc(), stc, Id::__fieldPostblit);
dd->storage_class |= STCinference;
dd->fbody = a ? new CompoundStatement(loc, a) : NULL;
sd->postblits.shift(dd);
sd->members->push(dd);
Expand Down Expand Up @@ -931,6 +935,7 @@ FuncDeclaration *buildPostBlit(StructDeclaration *sd, Scope *sc)
e = Expression::combine(e, ex);
}
PostBlitDeclaration *dd = new PostBlitDeclaration(declLoc, Loc(), stc, Id::__aggrPostblit);
dd->storage_class |= STCinference;
dd->fbody = new ExpStatement(loc, e);
sd->members->push(dd);
dd->semantic(sc);
Expand Down Expand Up @@ -974,6 +979,7 @@ FuncDeclaration *buildDtor(AggregateDeclaration *ad, Scope *sc)
StructDeclaration *sdv = ((TypeStruct *)tv)->sym;
if (!sdv->dtor)
continue;
sdv->dtor->functionSemantic();

stc = mergeFuncAttrs(stc, sdv->dtor);
if (stc & STCdisable)
Expand Down Expand Up @@ -1026,6 +1032,7 @@ FuncDeclaration *buildDtor(AggregateDeclaration *ad, Scope *sc)
{
//printf("Building __fieldDtor()\n");
DtorDeclaration *dd = new DtorDeclaration(declLoc, Loc(), stc, Id::__fieldDtor);
dd->storage_class |= STCinference;
dd->fbody = new ExpStatement(loc, e);
ad->dtors.shift(dd);
ad->members->push(dd);
Expand Down Expand Up @@ -1060,6 +1067,7 @@ FuncDeclaration *buildDtor(AggregateDeclaration *ad, Scope *sc)
e = Expression::combine(ex, e);
}
DtorDeclaration *dd = new DtorDeclaration(declLoc, Loc(), stc, Id::__aggrDtor);
dd->storage_class |= STCinference;
dd->fbody = new ExpStatement(loc, e);
ad->members->push(dd);
dd->semantic(sc);
Expand Down
1 change: 1 addition & 0 deletions src/declaration.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ enum PINLINE;
#define STCnogc 0x40000000000LL // @nogc
#define STCvolatile 0x80000000000LL // destined for volatile in the back end
#define STCreturn 0x100000000000LL // 'return ref' for function parameters
#define STCinference 0x200000000000LL // do attribute inference

const StorageClass STCStorageClass = (STCauto | STCscope | STCstatic | STCextern | STCconst | STCfinal |
STCabstract | STCsynchronized | STCdeprecated | STCoverride | STClazy | STCalias |
Expand Down
14 changes: 4 additions & 10 deletions src/func.c
Original file line number Diff line number Diff line change
Expand Up @@ -1167,6 +1167,7 @@ void FuncDeclaration::semantic(Scope *sc)
TemplateInstance *ti;
if (fbody &&
(isFuncLiteralDeclaration() ||
(storage_class & STCinference) ||
(inferRetType && !isCtorDeclaration()) ||
isInstantiated() && !isVirtualMethod() &&
!(ti = parent->isTemplateInstance(), ti && !ti->isTemplateMixin() && ti->tempdecl->ident != ident)))
Expand Down Expand Up @@ -1244,9 +1245,7 @@ void FuncDeclaration::semantic3(Scope *sc)

if (ident == Id::assign && !inuse)
{
AggregateDeclaration *ad = isThis();
StructDeclaration *sd = ad ? ad->isStructDeclaration() : NULL;
if (sd && sd->fdassign == this)
if (storage_class & STCinference)
{
/* Bugzilla 15044: For generated opAssign function, any errors
* from its body need to be gagged.
Expand Down Expand Up @@ -2262,13 +2261,8 @@ bool FuncDeclaration::functionSemantic()
return functionSemantic3();
}

if (ident == Id::assign)
{
AggregateDeclaration *ad = isThis();
StructDeclaration *sd = ad ? ad->isStructDeclaration() : NULL;
if (sd && sd->fdassign == this)
return functionSemantic3();
}
if (storage_class & STCinference)
return functionSemantic3();

return true;
}
Expand Down
1 change: 1 addition & 0 deletions src/magicport.json
Original file line number Diff line number Diff line change
Expand Up @@ -1597,6 +1597,7 @@
"variable STCnogc",
"variable STCvolatile",
"variable STCreturn",
"variable STCinference",
"variable STCStorageClass",
"struct Match",
"enum Semantic",
Expand Down
1 change: 0 additions & 1 deletion src/struct.c
Original file line number Diff line number Diff line change
Expand Up @@ -675,7 +675,6 @@ StructDeclaration::StructDeclaration(Loc loc, Identifier *id)
hasIdentityAssign = false;
hasIdentityEquals = false;
postblit = NULL;
fdassign = NULL;

xeq = NULL;
xcmp = NULL;
Expand Down

0 comments on commit 664b202

Please sign in to comment.