Skip to content

Commit 6543040

Browse files
authored
Fixes #25304 proper test for hlo recursion limit (#25305)
The `warnUser` message kind is probably not the right one, but I left it as a placeholder. It should probably at least warn if not just straight up throw an error, was very hard to figure out what went wrong without any indication. The hard coded 300 should possibly also be changed to `evalTemplateLimit` or the VM call recursion limit or something.
1 parent 0f7b378 commit 6543040

File tree

2 files changed

+9
-11
lines changed

2 files changed

+9
-11
lines changed

compiler/hlo.nim

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
# This include implements the high level optimization pass.
1111
# included from sem.nim
1212

13-
proc hlo(c: PContext, n: PNode): PNode
13+
proc hlo(c: PContext, n: PNode, loopDetector: int): PNode
1414

1515
proc evalPattern(c: PContext, n, orig: PNode): PNode =
1616
internalAssert c.config, n.kind == nkCall and n[0].kind == nkSym
@@ -61,10 +61,11 @@ proc applyPatterns(c: PContext, n: PNode): PNode =
6161
# activate this pattern again:
6262
c.patterns[i] = pattern
6363

64-
proc hlo(c: PContext, n: PNode): PNode =
65-
inc(c.hloLoopDetector)
64+
proc hlo(c: PContext, n: PNode, loopDetector: int): PNode =
6665
# simply stop and do not perform any further transformations:
67-
if c.hloLoopDetector > 300: return n
66+
if loopDetector > 300:
67+
message(c.config, n.info, warnUser, "term rewrite macro instantiation too nested")
68+
return n
6869
case n.kind
6970
of nkMacroDef, nkTemplateDef, procDefs:
7071
# already processed (special cases in semstmts.nim)
@@ -80,7 +81,7 @@ proc hlo(c: PContext, n: PNode): PNode =
8081
# no optimization applied, try subtrees:
8182
for i in 0..<result.safeLen:
8283
let a = result[i]
83-
let h = hlo(c, a)
84+
let h = hlo(c, a, loopDetector)
8485
if h != a: result[i] = h
8586
else:
8687
# perform type checking, so that the replacement still fits:
@@ -90,17 +91,15 @@ proc hlo(c: PContext, n: PNode): PNode =
9091
result = fitNode(c, n.typ, result, n.info)
9192
# optimization has been applied so check again:
9293
result = commonOptimizations(c.graph, c.idgen, c.module, result)
93-
result = hlo(c, result)
94+
result = hlo(c, result, loopDetector + 1)
9495
result = commonOptimizations(c.graph, c.idgen, c.module, result)
9596

9697
proc hloBody(c: PContext, n: PNode): PNode =
9798
# fast exit:
9899
if c.patterns.len == 0 or optTrMacros notin c.config.options: return n
99-
c.hloLoopDetector = 0
100-
result = hlo(c, n)
100+
result = hlo(c, n, 0)
101101

102102
proc hloStmt(c: PContext, n: PNode): PNode =
103103
# fast exit:
104104
if c.patterns.len == 0 or optTrMacros notin c.config.options: return n
105-
c.hloLoopDetector = 0
106-
result = hlo(c, n)
105+
result = hlo(c, n, 0)

compiler/semdata.nim

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,6 @@ type
153153
generics*: seq[TInstantiationPair] # pending list of instantiated generics to compile
154154
topStmts*: int # counts the number of encountered top level statements
155155
lastGenericIdx*: int # used for the generics stack
156-
hloLoopDetector*: int # used to prevent endless loops in the HLO
157156
inParallelStmt*: int
158157
instTypeBoundOp*: proc (c: PContext; dc: PSym; t: PType; info: TLineInfo;
159158
op: TTypeAttachedOp; col: int): PSym {.nimcall.}

0 commit comments

Comments
 (0)