File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -715,7 +715,7 @@ addToLifetimesMappingsIfRef internal xobj =
715715 pure ()
716716 where
717717 makeLifetimeMode =
718- if internal
718+ if internal && not refTargetIsGlobal
719719 then
720720 LifetimeInsideFunction $
721721 Set. fromList
@@ -724,6 +724,13 @@ addToLifetimesMappingsIfRef internal xobj =
724724 _ -> varOfXObj xobj
725725 ]
726726 else LifetimeOutsideFunction
727+ refTargetIsGlobal =
728+ case xobj of
729+ XObj (Lst [XObj Ref _ _, target]) _ _ ->
730+ isGlobalFunc target || isGlobalVariable target
731+ _ -> False
732+ isGlobalVariable (XObj (Sym _ (LookupGlobal _ _)) _ _) = True
733+ isGlobalVariable _ = False
727734 mergeLifetimeMode LifetimeOutsideFunction LifetimeOutsideFunction = LifetimeOutsideFunction
728735 mergeLifetimeMode (LifetimeInsideFunction a) (LifetimeInsideFunction b) = LifetimeInsideFunction (Set. union a b)
729736 mergeLifetimeMode (LifetimeInsideFunction a) LifetimeOutsideFunction = LifetimeMixed a
Original file line number Diff line number Diff line change 1+ (load "Test.carp")
2+ (use Test)
3+
4+ ; Regression test: a reference to a global function (e.g. `&str` passed to
5+ ; copy-map) inside a while/for body used to fail the memory checker's second
6+ ; pass over the loop with "reference isn't alive".
7+
8+ (deftype T (A [Long]) (B []))
9+ (defmodule T
10+ (defn str [t]
11+ (match @t
12+ (T.A i) (Long.str i)
13+ (T.B) @"b"))
14+ (implements str T.str))
15+
16+ (defn join-in-loop []
17+ (let-do [acc []]
18+ (for [i 0 2]
19+ (set! acc (Array.push-back acc (Array.join ", " &(Array.copy-map &str &[(T.A 1l) (T.B)])))))
20+ (Array.join "; " &acc)))
21+
22+ (deftest test
23+ (assert-equal test
24+ "1, b; 1, b"
25+ &(join-in-loop)
26+ "refs to global functions inside loops stay alive"))
You can’t perform that action at this time.
0 commit comments