This commit is contained in:
Andreas Rumpf
2020-10-07 14:38:25 +02:00
committed by GitHub
parent acbe27b082
commit 0426a4d85a
2 changed files with 34 additions and 6 deletions

View File

@@ -48,7 +48,8 @@ proc dec(x: var AbstractTime; diff = 1) {.borrow.}
type
SubgraphFlag = enum
isMutated, # graph might be mutated
connectsConstParam, # graph is connected to a non-var parameter.
isMutatedDirectly, # graph is mutated directly by a non-var parameter.
connectsConstParam # graph is connected to a non-var parameter.
VarFlag = enum
ownsData,
@@ -99,12 +100,12 @@ type
config: ConfigRef
proc mutationAfterConnection(g: MutationInfo): bool {.inline.} =
#echo g.maxMutation, " ", g.minConnection, " ", g.param
#echo g.maxMutation.int, " ", g.minConnection.int, " ", g.param
g.maxMutation > g.minConnection
proc `$`*(config: ConfigRef; g: MutationInfo): string =
result = ""
if g.flags == {isMutated, connectsConstParam}:
if g.flags * {isMutated, connectsConstParam} == {isMutated, connectsConstParam}:
result.add "\nan object reachable from '"
result.add g.param.name.s
result.add "' is potentially mutated"
@@ -119,7 +120,8 @@ proc `$`*(config: ConfigRef; g: MutationInfo): string =
proc hasSideEffect*(c: var Partitions; info: var MutationInfo): bool =
for g in mitems c.graphs:
if g.flags == {isMutated, connectsConstParam} and mutationAfterConnection(g):
if g.flags * {isMutated, connectsConstParam} == {isMutated, connectsConstParam} and
(mutationAfterConnection(g) or isMutatedDirectly in g.flags):
info = g
return true
return false
@@ -173,11 +175,16 @@ proc potentialMutation(v: var Partitions; s: PSym; info: TLineInfo) =
let id = variableId(v, s)
if id >= 0:
let r = root(v, id)
let flags = if s.kind == skParam and isConstParam(s):
{isMutated, isMutatedDirectly}
else:
{isMutated}
case v.s[r].con.kind
of isEmptyRoot:
v.s[r].con = Connection(kind: isRootOf, graphIndex: v.graphs.len)
v.graphs.add MutationInfo(param: if isConstParam(s): s else: nil, mutatedHere: info,
connectedVia: unknownLineInfo, flags: {isMutated},
connectedVia: unknownLineInfo, flags: flags,
maxMutation: v.abstractTime, minConnection: MaxTime,
mutations: @[v.abstractTime])
of isRootOf:
@@ -187,7 +194,7 @@ proc potentialMutation(v: var Partitions; s: PSym; info: TLineInfo) =
if v.abstractTime > g.maxMutation:
g.mutatedHere = info
g.maxMutation = v.abstractTime
g.flags.incl isMutated
g.flags.incl flags
g.mutations.add v.abstractTime
else:
assert false, "cannot happen"

View File

@@ -0,0 +1,21 @@
discard """
errormsg: "'edit' can have side effects"
nimout: '''an object reachable from 'x' is potentially mutated
tfuncs_cannot_mutate_simple.nim(17, 4) the mutation is here'''
line: 16
"""
{.experimental: "strictFuncs".}
# bug #15508
type
MyType = ref object
data: string
func edit(x: MyType) =
x.data = "hello"
let x = MyType()
x.edit()
echo x.data