mirror of
https://github.com/nim-lang/Nim.git
synced 2026-04-19 22:10:33 +00:00
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
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -76,7 +76,7 @@ Advanced options:
|
||||
--NimblePath:PATH add a path for Nimble support
|
||||
--noNimblePath deactivate the Nimble path
|
||||
--noCppExceptions use default exception handling with C++ backend
|
||||
--cppCompileToNamespace use namespace "Nim" for the generated C++ code
|
||||
--cppCompileToNamespace use namespace "Nim" for the generated C++ code
|
||||
--excludePath:PATH exclude a path from the list of search paths
|
||||
--dynlibOverride:SYMBOL marks SYMBOL so that dynlib:SYMBOL
|
||||
has no effect and can be statically linked instead;
|
||||
|
||||
Reference in New Issue
Block a user