diff options
author | jcosborn <jcosborn@users.noreply.github.com> | 2018-04-19 15:39:18 -0500 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2018-04-19 22:39:18 +0200 |
commit | 7e15d5134bb4c98a96307d16621eb836543bb083 (patch) | |
tree | f666da8434bf46e1bbc4858e9d30d0104fac12e4 /compiler | |
parent | 34029263725ef931863ea73966dc08588758dada (diff) | |
download | Nim-7e15d5134bb4c98a96307d16621eb836543bb083.tar.gz |
allow setting template/macro recursive evaluation limits (#7652)
* allow setting template/macro recursive evaluation limits * revert setting template/macro eval limits set them to 1000
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/commands.nim | 1 | ||||
-rw-r--r-- | compiler/evaltempl.nim | 5 | ||||
-rw-r--r-- | compiler/hlo.nim | 2 | ||||
-rw-r--r-- | compiler/msgs.nim | 6 | ||||
-rw-r--r-- | compiler/sem.nim | 2 | ||||
-rw-r--r-- | compiler/vm.nim | 6 |
6 files changed, 13 insertions, 9 deletions
diff --git a/compiler/commands.nim b/compiler/commands.nim index 820cb7e1a..7274004a9 100644 --- a/compiler/commands.nim +++ b/compiler/commands.nim @@ -702,7 +702,6 @@ proc processSwitch(switch, arg: string, pass: TCmdLinePass, info: TLineInfo; expectNoArg(switch, arg, pass, info) useNimNamespace = true defineSymbol("cppCompileToNamespace") - else: if strutils.find(switch, '.') >= 0: options.setConfigVar(switch, arg) else: invalidCmdLineOption(pass, switch, info) diff --git a/compiler/evaltempl.nim b/compiler/evaltempl.nim index 704ff819c..fbb7eb2e6 100644 --- a/compiler/evaltempl.nim +++ b/compiler/evaltempl.nim @@ -106,8 +106,9 @@ proc evalTemplateArgs(n: PNode, s: PSym; fromHlo: bool): PNode = for i in 1 .. genericParams: result.addSon n.sons[givenRegularParams + i] +# to prevent endless recursion in template instantiation +const evalTemplateLimit* = 1000 var evalTemplateCounter* = 0 - # to prevent endless recursion in templates instantiation proc wrapInComesFrom*(info: TLineInfo; sym: PSym; res: PNode): PNode = when true: @@ -133,7 +134,7 @@ proc wrapInComesFrom*(info: TLineInfo; sym: PSym; res: PNode): PNode = proc evalTemplate*(n: PNode, tmpl, genSymOwner: PSym; fromHlo=false): PNode = inc(evalTemplateCounter) - if evalTemplateCounter > 100: + if evalTemplateCounter > evalTemplateLimit: globalError(n.info, errTemplateInstantiationTooNested) result = n diff --git a/compiler/hlo.nim b/compiler/hlo.nim index 2bffaa173..c4288c362 100644 --- a/compiler/hlo.nim +++ b/compiler/hlo.nim @@ -44,7 +44,7 @@ proc applyPatterns(c: PContext, n: PNode): PNode = assert x.kind in {nkStmtList, nkCall} # better be safe than sorry, so check evalTemplateCounter too: inc(evalTemplateCounter) - if evalTemplateCounter > 100: + if evalTemplateCounter > evalTemplateLimit: globalError(n.info, errTemplateInstantiationTooNested) # deactivate this pattern: c.patterns[i] = nil diff --git a/compiler/msgs.nim b/compiler/msgs.nim index 818ab0c05..749d29b55 100644 --- a/compiler/msgs.nim +++ b/compiler/msgs.nim @@ -87,7 +87,8 @@ type errNoReturnTypeDeclared, errNoCommand, errInvalidCommandX, errXOnlyAtModuleScope, errXNeedsParamObjectType, - errTemplateInstantiationTooNested, errInstantiationFrom, + errTemplateInstantiationTooNested, errMacroInstantiationTooNested, + errInstantiationFrom, errInvalidIndexValueForTuple, errCommandExpectsFilename, errMainModuleMustBeSpecified, errXExpected, @@ -329,7 +330,8 @@ const errInvalidCommandX: "invalid command: \'$1\'", errXOnlyAtModuleScope: "\'$1\' is only allowed at top level", errXNeedsParamObjectType: "'$1' needs a parameter that has an object type", - errTemplateInstantiationTooNested: "template/macro instantiation too nested", + errTemplateInstantiationTooNested: "template instantiation too nested, try --evalTemplateLimit:N", + errMacroInstantiationTooNested: "macro instantiation too nested, try --evalMacroLimit:N", errInstantiationFrom: "template/generic instantiation from here", errInvalidIndexValueForTuple: "invalid index value for tuple subscript", errCommandExpectsFilename: "command expects a filename argument", diff --git a/compiler/sem.nim b/compiler/sem.nim index 4fef1bc60..041f2e127 100644 --- a/compiler/sem.nim +++ b/compiler/sem.nim @@ -377,7 +377,7 @@ proc semAfterMacroCall(c: PContext, call, macroResult: PNode, ## reassigned, and binding the unbound identifiers that the macro output ## contains. inc(evalTemplateCounter) - if evalTemplateCounter > 100: + if evalTemplateCounter > evalTemplateLimit: globalError(s.info, errTemplateInstantiationTooNested) c.friendModules.add(s.owner.getModule) diff --git a/compiler/vm.nim b/compiler/vm.nim index 5ef782abd..5b5ccdce4 100644 --- a/compiler/vm.nim +++ b/compiler/vm.nim @@ -1729,14 +1729,16 @@ iterator genericParamsInMacroCall*(macroSym: PSym, call: PNode): (PSym, PNode) = let posInCall = macroSym.typ.len + i yield (genericParam, call[posInCall]) +# to prevent endless recursion in macro instantiation +const evalMacroLimit = 1000 var evalMacroCounter: int proc evalMacroCall*(module: PSym; cache: IdentCache, n, nOrig: PNode, sym: PSym): PNode = # XXX globalError() is ugly here, but I don't know a better solution for now inc(evalMacroCounter) - if evalMacroCounter > 100: - globalError(n.info, errTemplateInstantiationTooNested) + if evalMacroCounter > evalMacroLimit: + globalError(n.info, errMacroInstantiationTooNested) # immediate macros can bypass any type and arity checking so we check the # arity here too: |