This commit is contained in:
Araq 2015-03-12 01:44:57 +01:00
commit f514be0772
4 changed files with 77 additions and 22 deletions

View file

@ -203,6 +203,17 @@ proc flowVarKind(t: PType): TFlowVarKind =
elif containsGarbageCollectedRef(t): fvInvalid elif containsGarbageCollectedRef(t): fvInvalid
else: fvBlob else: fvBlob
proc typeNeedsNoDeepCopy(t: PType): bool =
var t = t.skipTypes(abstractInst)
# for the tconvexhull example (and others) we're a bit lax here and pretend
# seqs and strings are *by value* only and 'shallow' doesn't exist!
if t.kind == tyString: return true
# note that seq[T] is fine, but 'var seq[T]' is not, so we need to skip 'var'
# for the stricter check and likewise we can skip 'seq' for a less
# strict check:
if t.kind in {tyVar, tySequence}: t = t.sons[0]
result = not containsGarbageCollectedRef(t)
proc addLocalVar(varSection, varInit: PNode; owner: PSym; typ: PType; proc addLocalVar(varSection, varInit: PNode; owner: PSym; typ: PType;
v: PNode; useShallowCopy=false): PSym = v: PNode; useShallowCopy=false): PSym =
result = newSym(skTemp, getIdent(genPrefix), owner, varSection.info) result = newSym(skTemp, getIdent(genPrefix), owner, varSection.info)
@ -215,7 +226,7 @@ proc addLocalVar(varSection, varInit: PNode; owner: PSym; typ: PType;
vpart.sons[2] = if varInit.isNil: v else: ast.emptyNode vpart.sons[2] = if varInit.isNil: v else: ast.emptyNode
varSection.add vpart varSection.add vpart
if varInit != nil: if varInit != nil:
if useShallowCopy: if useShallowCopy and typeNeedsNoDeepCopy(typ):
varInit.add newFastAsgnStmt(newSymNode(result), v) varInit.add newFastAsgnStmt(newSymNode(result), v)
else: else:
let deepCopyCall = newNodeI(nkCall, varInit.info, 3) let deepCopyCall = newNodeI(nkCall, varInit.info, 3)

View file

@ -6,7 +6,7 @@ true
true true
true''' true'''
ccodeCheck: "!'deepcopy('" ccodeCheck: "\\i ! @'deepCopy(' .*"
""" """
# parallel convex hull for Nim bigbreak # parallel convex hull for Nim bigbreak

View file

@ -0,0 +1,40 @@
discard """
ccodeCheck: "\\i @'deepCopy(' .*"
"""
# bug #2286
import threadPool
type
Person = ref object
name: string
friend: Person
var
people: seq[Person] = @[]
proc newPerson(name:string): Person =
result.new()
result.name = name
proc greet(p:Person) =
p.friend.name &= "-MUT" # this line crashes the program
echo "Person {",
" name:", p.name, "(", cast[int](addr p.name),"),",
" friend:", p.friend.name, "(", cast[int](addr p.friend.name),") }"
proc setup =
for i in 0 .. <20:
people.add newPerson("Person" & $(i + 1))
for i in 0 .. <20:
people[i].friend = people[19-i]
proc update =
parallel:
for i in 0 .. people.high:
spawn people[i].greet()
when isMainModule:
setup()
update()

View file

@ -148,7 +148,11 @@ proc codegenCheck(test: TTest, check: string, given: var TSpec) =
let genFile = generatedFile(path, name, test.target) let genFile = generatedFile(path, name, test.target)
echo genFile echo genFile
let contents = readFile(genFile).string let contents = readFile(genFile).string
if contents.find(check.peg) < 0: if check[0] == '\\':
# little hack to get 'match' support:
if not contents.match(check.peg):
given.err = reCodegenFailure
elif contents.find(check.peg) < 0:
given.err = reCodegenFailure given.err = reCodegenFailure
except ValueError: except ValueError:
given.err = reInvalidPeg given.err = reInvalidPeg