fixes #7637; assignments are not allowed to slice object; minor breaking change

This commit is contained in:
Andreas Rumpf
2018-04-21 21:22:36 +02:00
parent 14046d975d
commit 85ea9593b3
5 changed files with 46 additions and 15 deletions

View File

@@ -11,6 +11,10 @@
to deal with!
- Indexing into a ``cstring`` for the JS target is now mapped
to ``charCodeAt``.
- Assignments that would "slice" an object into its supertype are not prevented
at runtime. Use ``ref object`` with inheritance rather than ``object`` with
inheritance to prevent this issue.
#### Breaking changes in the standard library

View File

@@ -79,8 +79,12 @@ proc genericAssignAux(dest, src: pointer, mt: PNimType, shallow: bool) =
GenericSeqSize),
mt.base, shallow)
of tyObject:
if mt.base != nil:
genericAssignAux(dest, src, mt.base, shallow)
var it = mt.base
# don't use recursion here on the PNimType because the subtype
# check should only be done at the very end:
while it != nil:
genericAssignAux(dest, src, it.node, shallow)
it = it.base
genericAssignAux(dest, src, mt.node, shallow)
# we need to copy m_type field for tyObject, as it could be empty for
# sequence reallocations:
@@ -89,6 +93,8 @@ proc genericAssignAux(dest, src: pointer, mt: PNimType, shallow: bool) =
# if p of TB:
# var tbObj = TB(p)
# tbObj of TC # needs to be false!
#c_fprintf(stdout, "%s %s\n", pint[].name, mt.name)
chckObjAsgn(cast[ptr PNimType](src)[], mt)
pint[] = mt # cast[ptr PNimType](src)[]
of tyTuple:
genericAssignAux(dest, src, mt.node, shallow)

View File

@@ -1,9 +1,7 @@
discard """
output: '''tbObj of TC false
false
output: '''tbObj of TC true
true
5
false'''
5'''
"""
# bug #1053
@@ -20,10 +18,10 @@ type
proc test(p: TA) =
#echo "p of TB ", p of TB
if p of TB:
var tbObj = TB(p)
#var tbObj = TB(p)
# tbObj is actually no longer compatible with TC:
echo "tbObj of TC ", tbObj of TC
echo "tbObj of TC ", p of TC
var v = TC()
v.a = 1
@@ -48,8 +46,8 @@ proc isMyObject(obj: TObject) =
asd.x = 5
var asdCopy = TObject(asd)
echo asdCopy of MyObject
#var asdCopy = TObject(asd)
#echo asdCopy of MyObject
isMyObject(asd)
isMyObject(asdCopy)
#isMyObject(asdCopy)

View File

@@ -0,0 +1,24 @@
discard """
outputsub: '''ObjectAssignmentError'''
exitcode: "1"
"""
# bug #7637
type
Fruit = object of RootObj
name*: string
Apple = object of Fruit
Pear = object of Fruit
method eat(f: Fruit) {.base.} =
raise newException(Exception, "PURE VIRTUAL CALL")
method eat(f: Apple) =
echo "fruity"
method eat(f: Pear) =
echo "juicy"
let basket = [Apple(name:"a"), Pear(name:"b")]
eat(basket[0])

View File

@@ -9,8 +9,8 @@ discard """
(k: kindA, a: (x: "abc", z: [1, 8, 3]), method: ())
(k: kindA, a: (x: "abc", z: [1, 9, 3]), method: ())
(k: kindA, a: (x: "abc", z: [1, 10, 3]), method: ())
(x: 123)
(x: 123)
(y: 0, x: 123)
(y: 678, x: 123)
(z: 89, y: 0, x: 128)
(y: 678, x: 123)
(y: 678, x: 123)
@@ -33,7 +33,6 @@ type
`method`: TEmpty # bug #1791
proc `$`[T](s: seq[T]): string =
# XXX why is that not in the stdlib?
result = "["
for i, x in s:
if i > 0: result.add(", ")
@@ -59,7 +58,7 @@ type
# inherited fields are ignored, so no fields are set
when true:
var
o: A
o: B
o = B(x: 123)
echo o
o = B(y: 678, x: 123)