Skip to content

Commit

Permalink
Merge pull request #3874 from 9rnsr/fix13299
Browse files Browse the repository at this point in the history
[REG2.066a] Issue 13299 - Property not found with typesafe variadic opDispatch
  • Loading branch information
WalterBright authored and 9rnsr committed Aug 26, 2014
1 parent 9b23adf commit b2476cd
Show file tree
Hide file tree
Showing 20 changed files with 287 additions and 198 deletions.
1 change: 0 additions & 1 deletion src/clone.c
Expand Up @@ -309,7 +309,6 @@ FuncDeclaration *buildOpAssign(StructDeclaration *sd, Scope *sc)
Scope *sc2 = sc->push();
sc2->stc = 0;
sc2->linkage = LINKd;
sc2->speculative = true;

fop->semantic(sc2);
fop->semantic2(sc2);
Expand Down
1 change: 1 addition & 0 deletions src/cond.c
Expand Up @@ -353,6 +353,7 @@ int StaticIfCondition::include(Scope *sc, ScopeDsymbol *sds)
++nest;
sc = sc->push(sc->scopesym);
sc->sds = sds; // sds gets any addMember()
//sc->speculative = true; // TODO: static if (is(T U)) { /* U is available */ }
sc->flags |= SCOPEstaticif;

sc = sc->startCTFE();
Expand Down
1 change: 0 additions & 1 deletion src/declaration.h
Expand Up @@ -712,7 +712,6 @@ class FuncDeclaration : public Declaration

Symbol *toThunkSymbol(int offset); // thunk version
void toObjFile(bool multiobj); // compile to .obj file
bool needsCodegen();

FuncDeclaration *isFuncDeclaration() { return this; }

Expand Down
12 changes: 11 additions & 1 deletion src/dsymbol.c
Expand Up @@ -326,13 +326,23 @@ TemplateInstance *Dsymbol::isSpeculative()
while (par)
{
TemplateInstance *ti = par->isTemplateInstance();
if (ti && ti->speculative)
if (ti && ti->gagged)
return ti;
par = par->toParent();
}
return NULL;
}

Ungag Dsymbol::ungagSpeculative()
{
unsigned oldgag = global.gag;

if (global.gag && !isSpeculative() && !toParent2()->isFuncDeclaration())
global.gag = 0;

return Ungag(oldgag);
}

bool Dsymbol::isAnonymous()
{
return ident == NULL;
Expand Down
9 changes: 7 additions & 2 deletions src/dsymbol.h
Expand Up @@ -82,8 +82,13 @@ typedef union tree_node TYPE;
struct TYPE;
#endif

// Back end
struct Classsym;
struct Ungag
{
unsigned oldgag;

Ungag(unsigned old) : oldgag(old) {}
~Ungag() { global.gag = oldgag; }
};

const char *mangle(Dsymbol *s);
const char *mangleExact(FuncDeclaration *fd);
Expand Down
11 changes: 4 additions & 7 deletions src/expression.c
Expand Up @@ -5116,11 +5116,10 @@ Expression *NewAnonClassExp::semantic(Scope *sc)
#endif

Expression *d = new DeclarationExp(loc, cd);
sc = sc->startCTFE(); // just create new scope
sc = sc->push(); // just create new scope
sc->flags &= ~SCOPEctfe; // temporary stop CTFE
d = d->semantic(sc);
sc->flags |= SCOPEctfe;
sc = sc->endCTFE();
sc = sc->pop();

Expression *n = new NewExp(loc, thisexp, newargs, cd->type, arguments);

Expand Down Expand Up @@ -5574,7 +5573,7 @@ Expression *FuncExp::semantic(Scope *sc)
#endif
Expression *e = this;

sc = sc->startCTFE(); // just create new scope
sc = sc->push(); // just create new scope
sc->flags &= ~SCOPEctfe; // temporary stop CTFE
sc->protection = PROTpublic; // Bugzilla 12506

Expand Down Expand Up @@ -5671,8 +5670,7 @@ Expression *FuncExp::semantic(Scope *sc)
fd->tookAddressOf++;
}
Ldone:
sc->flags |= SCOPEctfe;
sc = sc->endCTFE();
sc = sc->pop();
return e;
}

Expand Down Expand Up @@ -14008,7 +14006,6 @@ Expression *resolveOpDollar(Scope *sc, ArrayExp *ae, Expression **pe0)

unsigned xerrors = global.startGagging();
sc = sc->push();
sc->speculative = true;
FuncDeclaration *fslice = resolveFuncCall(ae->loc, sc, slice, tiargs, ae->e1->type, fargs, 1);
sc = sc->pop();
global.endGagging(xerrors);
Expand Down
96 changes: 5 additions & 91 deletions src/func.c
Expand Up @@ -1269,7 +1269,6 @@ void FuncDeclaration::semantic3(Scope *sc)
sc2->tf = NULL;
sc2->os = NULL;
sc2->noctor = 0;
sc2->speculative = sc->speculative || isSpeculative() != NULL;
sc2->userAttribDecl = NULL;
if (sc2->intypeof == 1) sc2->intypeof = 2;
sc2->fieldinit = NULL;
Expand Down Expand Up @@ -2168,7 +2167,7 @@ void FuncDeclaration::semantic3(Scope *sc)
sc = sc->pop();
}

/* If this function had speculatively instantiated, error reproduction will be
/* If this function had instantiated with gagging, error reproduction will be
* done by TemplateInstance::semantic.
* Otherwise, error gagging should be temporarily ungagged by functionSemantic3.
*/
Expand All @@ -2195,7 +2194,7 @@ bool FuncDeclaration::functionSemantic()
semantic(scope);
global.gag = oldgag;
if (spec && global.errors != olderrs)
spec->errors = global.errors - olderrs != 0;
spec->errors = (global.errors - olderrs != 0);
if (olderrs != global.errors) // if errors compiling this function
return false;
}
Expand Down Expand Up @@ -2229,8 +2228,8 @@ bool FuncDeclaration::functionSemantic3()
if (semanticRun < PASSsemantic3 && scope)
{
/* Forward reference - we need to run semantic3 on this function.
* If errors are gagged, and it's not part of a speculative
* template instance, we need to temporarily ungag errors.
* If errors are gagged, and it's not part of a template instance,
* we need to temporarily ungag errors.
*/
TemplateInstance *spec = isSpeculative();
unsigned olderrs = global.errors;
Expand All @@ -2243,7 +2242,7 @@ bool FuncDeclaration::functionSemantic3()
// If it is a speculatively-instantiated template, and errors occur,
// we need to mark the template as having errors.
if (spec && global.errors != olderrs)
spec->errors = global.errors - olderrs != 0;
spec->errors = (global.errors - olderrs != 0);
if (olderrs != global.errors) // if errors compiling this function
return false;
}
Expand Down Expand Up @@ -4253,91 +4252,6 @@ bool FuncDeclaration::hasNestedFrameRefs()
return false;
}

/***********************************************
* Returns true if this function is not defined in non-root module, nor
* obviously instantiated in non-root module.
*
* Note: ti->instantiatingModule does not stabilize until semantic analysis is completed,
* so don't call this function during semantic analysis to return precise result.
*/

bool FuncDeclaration::needsCodegen()
{
assert(semanticRun == PASSsemantic3done);

for (FuncDeclaration *fd = this; fd; )
{
if (!fd->isInstantiated() && fd->inNonRoot())
return false;
if (fd->isNested())
fd = fd->toParent2()->isFuncDeclaration();
else
break;
}

/* The issue is that if the importee is compiled with a different -debug
* setting than the importer, the importer may believe it exists
* in the compiled importee when it does not, when the instantiation
* is behind a conditional debug declaration.
*/
// workaround for Bugzilla 11239
if (global.params.useUnitTests ||
global.params.allInst ||
global.params.debuglevel)
{
return true;
}

FuncDeclaration *fd = this;
Lagain:
TemplateInstance *ti = fd->isInstantiated();
if (ti && ti->instantiatingModule && !ti->instantiatingModule->isRoot())
{
Module *mi = ti->instantiatingModule;

// If mi imports any root modules, we still need to generate the code.
for (size_t i = 0; i < Module::amodules.dim; ++i)
{
Module *m = Module::amodules[i];
m->insearch = 0;
}
bool importsRoot = false;
for (size_t i = 0; i < Module::amodules.dim; ++i)
{
Module *m = Module::amodules[i];
if (m->isRoot() && mi->imports(m))
{
importsRoot = true;
break;
}
}
for (size_t i = 0; i < Module::amodules.dim; ++i)
{
Module *m = Module::amodules[i];
m->insearch = 0;
}
if (!importsRoot)
{
//printf("instantiated by %s %s\n", ti->instantiatingModule->toChars(), ti->toChars());
return false;
}
}

if (fd->isNested())
{
/* Bugzilla 11863: The enclosing function must have its code generated first.
* Therefore if parent is instantiated in non-root, this function also prevent
* code generation.
*/
fd = fd->toParent2()->isFuncDeclaration();
if (fd)
goto Lagain;
}
//if (AggregateDeclaration *ad = fd->isMember2()) { ... }

return true;
}

/*********************************************
* Return the function's parameter list, and whether
* it is variadic or not.
Expand Down

0 comments on commit b2476cd

Please sign in to comment.