From bb0d51fb9813f5d0855718f5db8a08fd28adec48 Mon Sep 17 00:00:00 2001 From: Alexey Prokhin Date: Tue, 14 Feb 2012 15:17:59 +0400 Subject: [PATCH] Don't resolve template instances that were instantiated inside static if or statis assert --- dmd2/interpret.c | 2 ++ dmd2/mtype.c | 1 + dmd2/scope.c | 2 ++ dmd2/scope.h | 1 + dmd2/staticassert.c | 1 + dmd2/template.c | 9 +++++++-- dmd2/template.h | 2 +- gen/declarations.cpp | 5 +++++ 8 files changed, 20 insertions(+), 3 deletions(-) diff --git a/dmd2/interpret.c b/dmd2/interpret.c index 4056d686..3d82d385 100644 --- a/dmd2/interpret.c +++ b/dmd2/interpret.c @@ -478,7 +478,9 @@ Expression *FuncDeclaration::interpret(InterState *istate, Expressions *argument TemplateInstance *spec = isSpeculativeFunction(this); if (global.gag && !spec) global.gag = 0; + ++scope->ignoreTemplates; semantic3(scope); + --scope->ignoreTemplates; global.gag = oldgag; // regag errors // If it is a speculatively-instantiated template, and errors occur, diff --git a/dmd2/mtype.c b/dmd2/mtype.c index 443c6083..3818e0f4 100644 --- a/dmd2/mtype.c +++ b/dmd2/mtype.c @@ -6920,6 +6920,7 @@ Type *TypeTypeof::semantic(Loc loc, Scope *sc) { Scope *sc2 = sc->push(); sc2->intypeof++; + sc2->ignoreTemplates++; sc2->flags |= sc->flags & SCOPEstaticif; exp = exp->semantic(sc2); #if DMDV2 diff --git a/dmd2/scope.c b/dmd2/scope.c index bbabc0c9..a23654e9 100644 --- a/dmd2/scope.c +++ b/dmd2/scope.c @@ -76,6 +76,7 @@ Scope::Scope() this->mustsemantic = 0; this->intypeof = 0; this->parameterSpecialization = 0; + this->ignoreTemplates = 0; this->callSuper = 0; this->flags = 0; this->anonAgg = NULL; @@ -125,6 +126,7 @@ Scope::Scope(Scope *enclosing) this->mustsemantic = enclosing->mustsemantic; this->intypeof = enclosing->intypeof; this->parameterSpecialization = enclosing->parameterSpecialization; + this->ignoreTemplates = enclosing->ignoreTemplates; this->callSuper = enclosing->callSuper; this->flags = 0; this->anonAgg = NULL; diff --git a/dmd2/scope.h b/dmd2/scope.h index 7eafd6be..ea725f09 100644 --- a/dmd2/scope.h +++ b/dmd2/scope.h @@ -71,6 +71,7 @@ struct Scope int parameterSpecialization; // if in template parameter specialization int noaccesscheck; // don't do access checks int mustsemantic; // cannot defer semantic() + int ignoreTemplates; // set if newly instantiated templates should be ignored when codegen'ing unsigned callSuper; // primitive flow analysis for constructors #define CSXthis_ctor 1 // called this() diff --git a/dmd2/staticassert.c b/dmd2/staticassert.c index 4d8bfa42..8e3dcefa 100644 --- a/dmd2/staticassert.c +++ b/dmd2/staticassert.c @@ -56,6 +56,7 @@ void StaticAssert::semantic2(Scope *sc) ScopeDsymbol *sd = new ScopeDsymbol(); sc = sc->push(sd); sc->flags |= SCOPEstaticassert; + ++sc->ignoreTemplates; Expression *e = exp->semantic(sc); sc = sc->pop(); if (e->type == Type::terror) diff --git a/dmd2/template.c b/dmd2/template.c index 18923b0c..fa634815 100644 --- a/dmd2/template.c +++ b/dmd2/template.c @@ -1658,6 +1658,7 @@ Lmatch: */ makeParamNamesVisibleInConstraint(paramscope, fargs); Expression *e = constraint->syntaxCopy(); + paramscope->ignoreTemplates++; paramscope->flags |= SCOPEstaticif; /* Detect recursive attempts to instantiate this template declaration, @@ -4206,9 +4207,9 @@ TemplateInstance::TemplateInstance(Loc loc, Identifier *ident) this->isnested = NULL; this->errors = 0; this->speculative = 0; + this->ignore = true; #if IN_LLVM - // LDC this->emittedInModule = NULL; this->tmodule = NULL; #endif @@ -4241,9 +4242,9 @@ TemplateInstance::TemplateInstance(Loc loc, TemplateDeclaration *td, Objects *ti this->isnested = NULL; this->errors = 0; this->speculative = 0; + this->ignore = true; #if IN_LLVM - // LDC this->tinst = NULL; this->emittedInModule = NULL; this->tmodule = NULL; @@ -4303,6 +4304,8 @@ void TemplateInstance::semantic(Scope *sc, Expressions *fargs) } // return; } + if (!sc->ignoreTemplates) + ignore = false; #if LOG printf("\n+TemplateInstance::semantic('%s', this=%p)\n", toChars(), this); #endif @@ -5537,6 +5540,8 @@ void TemplateInstance::semantic3(Scope *sc) sc = sc->push(argsym); sc = sc->push(this); sc->tinst = this; + if (ignore) + sc->ignoreTemplates++; int oldgag = global.gag; int olderrors = global.errors; /* If this is a speculative instantiation, gag errors. diff --git a/dmd2/template.h b/dmd2/template.h index d4920b68..b659b46b 100644 --- a/dmd2/template.h +++ b/dmd2/template.h @@ -306,6 +306,7 @@ struct TemplateInstance : ScopeDsymbol Dsymbol *isnested; // if referencing local symbols, this is the context int errors; // 1 if compiled with errors int speculative; // 1 if only instantiated with errors gagged + bool ignore; // true if the instance must be ignored when codegen'ing #ifdef IN_GCC /* On some targets, it is necessary to know whether a symbol will be emitted in the output or not before the symbol @@ -348,7 +349,6 @@ struct TemplateInstance : ScopeDsymbol AliasDeclaration *isAliasDeclaration(); #if IN_LLVM - // LDC Module* tmodule; // module from outermost enclosing template instantiation Module* emittedInModule; // which module this template instance has been emitted in diff --git a/gen/declarations.cpp b/gen/declarations.cpp index b4c2a78a..6e4886b6 100644 --- a/gen/declarations.cpp +++ b/gen/declarations.cpp @@ -245,6 +245,11 @@ void TemplateInstance::codegen(Ir* p) #if LOG printf("TemplateInstance::toObjFile('%s', this = %p)\n", toChars(), this); #endif +#if DMDV2 + if (ignore) + return; +#endif + if (!errors && members) { for (unsigned i = 0; i < members->dim; i++)