# HG changeset patch # User Leandro Lucarella # Date 1262801901 10800 # Node ID 3da302cc4966f1ad04723bc4ce2ef1981f1e0ac7 # Parent dbf7b54f542f3375010bd4121093a310229e2aa7 Merge DMD r294: bugzilla 2816 Sudden-death static assert is not... bugzilla 2816 Sudden-death static assert is not very useful. --- dmd/expression.h | 12 ++++++ dmd/staticassert.c | 10 +--- dmd/template.c | 108 ++++++++++++++++++++++++++++++++++++++++++++++++---- dmd/template.h | 2 + 4 files changed, 117 insertions(+), 15 deletions(-) diff -r dbf7b54f542f -r 3da302cc4966 dmd/expression.h --- a/dmd/expression.h Wed Jan 06 15:18:21 2010 -0300 +++ b/dmd/expression.h Wed Jan 06 15:18:21 2010 -0300 @@ -1546,6 +1546,18 @@ #endif }; +#if DMDV2 +struct PowExp : BinExp +{ + PowExp(Loc loc, Expression *e1, Expression *e2); + Expression *semantic(Scope *sc); + + // For operator overloading + Identifier *opId(); + Identifier *opId_r(); +}; +#endif + struct ShlExp : BinExp { ShlExp(Loc loc, Expression *e1, Expression *e2); diff -r dbf7b54f542f -r 3da302cc4966 dmd/staticassert.c --- a/dmd/staticassert.c Wed Jan 06 15:18:21 2010 -0300 +++ b/dmd/staticassert.c Wed Jan 06 15:18:21 2010 -0300 @@ -18,6 +18,7 @@ #include "hdrgen.h" #include "scope.h" #include "template.h" +#include "declaration.h" /********************************* AttribDeclaration ****************************/ @@ -48,10 +49,6 @@ { } -#include "scope.h" -#include "template.h" -#include "declaration.h" - void StaticAssert::semantic2(Scope *sc) { Expression *e; @@ -73,11 +70,10 @@ } else error("(%s) is false", exp->toChars()); - if(sc->tinst) + if (sc->tinst) sc->tinst->printInstantiationTrace(); - if (!global.gag) { + if (!global.gag) fatal(); - } } else if (!e->isBool(TRUE)) { diff -r dbf7b54f542f -r 3da302cc4966 dmd/template.c --- a/dmd/template.c Wed Jan 06 15:18:21 2010 -0300 +++ b/dmd/template.c Wed Jan 06 15:18:21 2010 -0300 @@ -3497,7 +3497,28 @@ if (sc->func || dosemantic3) { - semantic3(sc2); +#if WINDOWS_SEH + __try + { +#endif + static int nest; + if (++nest > 300) + { + global.gag = 0; // ensure error message gets printed + error("recursive expansion"); + fatal(); + } + semantic3(sc2); + --nest; +#if WINDOWS_SEH + } + __except (__ehfilter(GetExceptionInformation())) + { + global.gag = 0; // ensure error message gets printed + error("recursive expansion"); + fatal(); + } +#endif } Laftersemantic: @@ -3509,7 +3530,7 @@ if (global.errors != errorsave) { error("error instantiating"); - if (tinst && !global.gag) + if (tinst) { tinst->printInstantiationTrace(); fatal(); } @@ -3672,7 +3693,7 @@ id = name; s = sc->search(loc, id, &scopesym); if (!s) - { error("identifier '%s' is not defined", id->toChars()); + { error("template '%s' is not defined", id->toChars()); return NULL; } #if LOG @@ -3978,20 +3999,18 @@ Identifier *TemplateInstance::genIdent() { OutBuffer buf; - char *id; - Objects *args; //printf("TemplateInstance::genIdent('%s')\n", tempdecl->ident->toChars()); - id = tempdecl->ident->toChars(); + char *id = tempdecl->ident->toChars(); buf.printf("__T%zu%s", strlen(id), id); - args = tiargs; + Objects *args = tiargs; for (int i = 0; i < args->dim; i++) { Object *o = (Object *)args->data[i]; Type *ta = isType(o); Expression *ea = isExpression(o); Dsymbol *sa = isDsymbol(o); Tuple *va = isTuple(o); - //printf("\to %p ta %p ea %p sa %p va %p\n", o, ta, ea, sa, va); + //printf("\to [%d] %p ta %p ea %p sa %p va %p\n", i, o, ta, ea, sa, va); if (ta) { buf.writeByte('T'); @@ -4191,10 +4210,81 @@ #if IN_DMD +/************************************** + * Given an error instantiating the TemplateInstance, + * give the nested TemplateInstance instantiations that got + * us here. Those are a list threaded into the nested scopes. + */ void TemplateInstance::printInstantiationTrace() { if (global.gag) return; + + const int max_shown = 6; + const char format[] = "%s: instantiated from here: %s\n"; + + // determine instantiation depth and number of recursive instantiations + int n_instantiations = 1; + int n_totalrecursions = 0; + for (TemplateInstance *cur = this; cur; cur = cur->tinst) + { + ++n_instantiations; + // If two instantiations use the same declaration, they are recursive. + // (this works even if they are instantiated from different places in the + // same template). + // In principle, we could also check for multiple-template recursion, but it's + // probably not worthwhile. + if (cur->tinst && cur->tempdecl && cur->tinst->tempdecl + && cur->tempdecl->loc.equals(cur->tinst->tempdecl->loc)) + ++n_totalrecursions; + } + + // show full trace only if it's short or verbose is on + if (n_instantiations <= max_shown || global.params.verbose) + { + for (TemplateInstance *cur = this; cur; cur = cur->tinst) + { + fprintf(stdmsg, format, cur->loc.toChars(), cur->toChars()); + } + } + else if (n_instantiations - n_totalrecursions <= max_shown) + { + // By collapsing recursive instantiations into a single line, + // we can stay under the limit. + int recursionDepth=0; + for (TemplateInstance *cur = this; cur; cur = cur->tinst) + { + if (cur->tinst && cur->tempdecl && cur->tinst->tempdecl + && cur->tempdecl->loc.equals(cur->tinst->tempdecl->loc)) + { + ++recursionDepth; + } + else + { + if (recursionDepth) + fprintf(stdmsg, "%s: %d recursive instantiations from here: %s\n", cur->loc.toChars(), recursionDepth+2, cur->toChars()); + else + fprintf(stdmsg,format, cur->loc.toChars(), cur->toChars()); + recursionDepth = 0; + } + } + } + else + { + // Even after collapsing the recursions, the depth is too deep. + // Just display the first few and last few instantiations. + size_t i = 0; + for (TemplateInstance *cur = this; cur; cur = cur->tinst) + { + if (i == max_shown / 2) + fprintf(stdmsg," ... (%d instantiations, -v to show) ...\n", n_instantiations - max_shown); + + if (i < max_shown / 2 || + i >= n_instantiations - max_shown + max_shown / 2) + fprintf(stdmsg, format, cur->loc.toChars(), cur->toChars()); + ++i; + } + } } void TemplateInstance::toObjFile(int multiobj) @@ -4277,7 +4367,9 @@ return inst->toAlias(); if (aliasdecl) + { return aliasdecl->toAlias(); + } return inst; } diff -r dbf7b54f542f -r 3da302cc4966 dmd/template.h --- a/dmd/template.h Wed Jan 06 15:18:21 2010 -0300 +++ b/dmd/template.h Wed Jan 06 15:18:21 2010 -0300 @@ -89,6 +89,8 @@ TemplateTupleParameter *isVariadic(); int isOverloadable(); + void makeParamNamesVisibleInConstraint(Scope *paramscope); + #if IN_LLVM // LDC std::string intrinsicName;