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:
parent
3402926372
commit
7e15d5134b
7 changed files with 14 additions and 10 deletions
|
|
@ -702,7 +702,6 @@ proc processSwitch(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
|
||||||
expectNoArg(switch, arg, pass, info)
|
expectNoArg(switch, arg, pass, info)
|
||||||
useNimNamespace = true
|
useNimNamespace = true
|
||||||
defineSymbol("cppCompileToNamespace")
|
defineSymbol("cppCompileToNamespace")
|
||||||
|
|
||||||
else:
|
else:
|
||||||
if strutils.find(switch, '.') >= 0: options.setConfigVar(switch, arg)
|
if strutils.find(switch, '.') >= 0: options.setConfigVar(switch, arg)
|
||||||
else: invalidCmdLineOption(pass, switch, info)
|
else: invalidCmdLineOption(pass, switch, info)
|
||||||
|
|
|
||||||
|
|
@ -106,8 +106,9 @@ proc evalTemplateArgs(n: PNode, s: PSym; fromHlo: bool): PNode =
|
||||||
for i in 1 .. genericParams:
|
for i in 1 .. genericParams:
|
||||||
result.addSon n.sons[givenRegularParams + i]
|
result.addSon n.sons[givenRegularParams + i]
|
||||||
|
|
||||||
|
# to prevent endless recursion in template instantiation
|
||||||
|
const evalTemplateLimit* = 1000
|
||||||
var evalTemplateCounter* = 0
|
var evalTemplateCounter* = 0
|
||||||
# to prevent endless recursion in templates instantiation
|
|
||||||
|
|
||||||
proc wrapInComesFrom*(info: TLineInfo; sym: PSym; res: PNode): PNode =
|
proc wrapInComesFrom*(info: TLineInfo; sym: PSym; res: PNode): PNode =
|
||||||
when true:
|
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 =
|
proc evalTemplate*(n: PNode, tmpl, genSymOwner: PSym; fromHlo=false): PNode =
|
||||||
inc(evalTemplateCounter)
|
inc(evalTemplateCounter)
|
||||||
if evalTemplateCounter > 100:
|
if evalTemplateCounter > evalTemplateLimit:
|
||||||
globalError(n.info, errTemplateInstantiationTooNested)
|
globalError(n.info, errTemplateInstantiationTooNested)
|
||||||
result = n
|
result = n
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ proc applyPatterns(c: PContext, n: PNode): PNode =
|
||||||
assert x.kind in {nkStmtList, nkCall}
|
assert x.kind in {nkStmtList, nkCall}
|
||||||
# better be safe than sorry, so check evalTemplateCounter too:
|
# better be safe than sorry, so check evalTemplateCounter too:
|
||||||
inc(evalTemplateCounter)
|
inc(evalTemplateCounter)
|
||||||
if evalTemplateCounter > 100:
|
if evalTemplateCounter > evalTemplateLimit:
|
||||||
globalError(n.info, errTemplateInstantiationTooNested)
|
globalError(n.info, errTemplateInstantiationTooNested)
|
||||||
# deactivate this pattern:
|
# deactivate this pattern:
|
||||||
c.patterns[i] = nil
|
c.patterns[i] = nil
|
||||||
|
|
|
||||||
|
|
@ -87,7 +87,8 @@ type
|
||||||
errNoReturnTypeDeclared,
|
errNoReturnTypeDeclared,
|
||||||
errNoCommand, errInvalidCommandX, errXOnlyAtModuleScope,
|
errNoCommand, errInvalidCommandX, errXOnlyAtModuleScope,
|
||||||
errXNeedsParamObjectType,
|
errXNeedsParamObjectType,
|
||||||
errTemplateInstantiationTooNested, errInstantiationFrom,
|
errTemplateInstantiationTooNested, errMacroInstantiationTooNested,
|
||||||
|
errInstantiationFrom,
|
||||||
errInvalidIndexValueForTuple, errCommandExpectsFilename,
|
errInvalidIndexValueForTuple, errCommandExpectsFilename,
|
||||||
errMainModuleMustBeSpecified,
|
errMainModuleMustBeSpecified,
|
||||||
errXExpected,
|
errXExpected,
|
||||||
|
|
@ -329,7 +330,8 @@ const
|
||||||
errInvalidCommandX: "invalid command: \'$1\'",
|
errInvalidCommandX: "invalid command: \'$1\'",
|
||||||
errXOnlyAtModuleScope: "\'$1\' is only allowed at top level",
|
errXOnlyAtModuleScope: "\'$1\' is only allowed at top level",
|
||||||
errXNeedsParamObjectType: "'$1' needs a parameter that has an object type",
|
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",
|
errInstantiationFrom: "template/generic instantiation from here",
|
||||||
errInvalidIndexValueForTuple: "invalid index value for tuple subscript",
|
errInvalidIndexValueForTuple: "invalid index value for tuple subscript",
|
||||||
errCommandExpectsFilename: "command expects a filename argument",
|
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
|
## reassigned, and binding the unbound identifiers that the macro output
|
||||||
## contains.
|
## contains.
|
||||||
inc(evalTemplateCounter)
|
inc(evalTemplateCounter)
|
||||||
if evalTemplateCounter > 100:
|
if evalTemplateCounter > evalTemplateLimit:
|
||||||
globalError(s.info, errTemplateInstantiationTooNested)
|
globalError(s.info, errTemplateInstantiationTooNested)
|
||||||
c.friendModules.add(s.owner.getModule)
|
c.friendModules.add(s.owner.getModule)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1729,14 +1729,16 @@ iterator genericParamsInMacroCall*(macroSym: PSym, call: PNode): (PSym, PNode) =
|
||||||
let posInCall = macroSym.typ.len + i
|
let posInCall = macroSym.typ.len + i
|
||||||
yield (genericParam, call[posInCall])
|
yield (genericParam, call[posInCall])
|
||||||
|
|
||||||
|
# to prevent endless recursion in macro instantiation
|
||||||
|
const evalMacroLimit = 1000
|
||||||
var evalMacroCounter: int
|
var evalMacroCounter: int
|
||||||
|
|
||||||
proc evalMacroCall*(module: PSym; cache: IdentCache, n, nOrig: PNode,
|
proc evalMacroCall*(module: PSym; cache: IdentCache, n, nOrig: PNode,
|
||||||
sym: PSym): PNode =
|
sym: PSym): PNode =
|
||||||
# XXX globalError() is ugly here, but I don't know a better solution for now
|
# XXX globalError() is ugly here, but I don't know a better solution for now
|
||||||
inc(evalMacroCounter)
|
inc(evalMacroCounter)
|
||||||
if evalMacroCounter > 100:
|
if evalMacroCounter > evalMacroLimit:
|
||||||
globalError(n.info, errTemplateInstantiationTooNested)
|
globalError(n.info, errMacroInstantiationTooNested)
|
||||||
|
|
||||||
# immediate macros can bypass any type and arity checking so we check the
|
# immediate macros can bypass any type and arity checking so we check the
|
||||||
# arity here too:
|
# arity here too:
|
||||||
|
|
|
||||||
|
|
@ -76,7 +76,7 @@ Advanced options:
|
||||||
--NimblePath:PATH add a path for Nimble support
|
--NimblePath:PATH add a path for Nimble support
|
||||||
--noNimblePath deactivate the Nimble path
|
--noNimblePath deactivate the Nimble path
|
||||||
--noCppExceptions use default exception handling with C++ backend
|
--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
|
--excludePath:PATH exclude a path from the list of search paths
|
||||||
--dynlibOverride:SYMBOL marks SYMBOL so that dynlib:SYMBOL
|
--dynlibOverride:SYMBOL marks SYMBOL so that dynlib:SYMBOL
|
||||||
has no effect and can be statically linked instead;
|
has no effect and can be statically linked instead;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue