bitsize respected in size calculation. (#9756)

This commit is contained in:
Arne Döring
2018-11-19 13:48:40 +01:00
committed by Andreas Rumpf
parent 2418d0cac5
commit 1e08fff2d5
3 changed files with 42 additions and 7 deletions

View File

@@ -1062,6 +1062,8 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int,
invalidPragma(c, it)
else:
sym.bitsize = expectIntLit(c, it)
if sym.bitsize <= 0:
localError(c.config, it.info, "bitsize needs to be positive")
of wGuard:
if sym == nil or sym.kind notin {skVar, skLet, skField}:
invalidPragma(c, it)

View File

@@ -127,9 +127,14 @@ proc computeObjectOffsetsFoldFunction(conf: ConfigRef; n: PNode, initialOffset:
result.offset = align(offset, result.align)
of nkSym:
computeSizeAlign(conf, n.sym.typ)
let size = n.sym.typ.size
let align = n.sym.typ.align
var size = szUnknownSize
var align = szUnknownSize
if n.sym.bitsize == 0: # 0 represents bitsize not set
computeSizeAlign(conf, n.sym.typ)
size = n.sym.typ.size.int
align = n.sym.typ.align.int
result.align = align
if initialOffset == szUnknownSize or size == szUnknownSize:
n.sym.offset = szUnknownSize

View File

@@ -10,14 +10,16 @@ type
TMyArray2 = array[1..3, int32]
TMyArray3 = array[TMyEnum, float64]
var failed = false
const
mysize1 = sizeof(TMyArray1)
mysize2 = sizeof(TMyArray2)
mysize3 = sizeof(TMyArray3)
assert mysize1 == 3
assert mysize2 == 12
assert mysize3 == 32
doAssert mysize1 == 3
doAssert mysize2 == 12
doAssert mysize3 == 32
import macros, typetraits
@@ -38,6 +40,7 @@ macro testSizeAlignOf(args: varargs[untyped]): untyped =
if nim_align != c_align:
msg.add " align(get, expected): " & $nim_align & " != " & $c_align
echo msg
failed = true
macro testOffsetOf(a,b1,b2: untyped): untyped =
@@ -49,6 +52,7 @@ macro testOffsetOf(a,b1,b2: untyped): untyped =
nim_offset = offsetof(`a`,`b2`)
if c_offset != nim_offset:
echo `typeName`, ".", `member`, " offsetError, C: ", c_offset, " nim: ", nim_offset
failed = true
template testOffsetOf(a,b: untyped): untyped =
testOffsetOf(a,b,b)
@@ -100,6 +104,16 @@ macro testAlign(arg:untyped):untyped =
let nimAlign = alignof(`arg`)
if cAlign != nimAlign:
echo `prefix`, cAlign, " != ", nimAlign
failed = true
macro testSize(arg:untyped):untyped =
let prefix = newLit(arg.lineinfo & " sizeof " & arg.repr & " ")
result = quote do:
let cSize = c_sizeof(`arg`)
let nimSize = sizeof(`arg`)
if cSize != nimSize:
echo `prefix`, cSize, " != ", nimSize
failed = true
type
MyEnum {.pure.} = enum
@@ -297,10 +311,20 @@ testinstance:
eoa: EnumObjectA
eob: EnumObjectB
testAlign(SimpleAlignment)
testSizeAlignOf(t,a,b,c,d,e,f,g,ro, e1, e2, e4, e8, eoa, eob)
when not defined(cpp):
type
WithBitsize {.objectconfig.} = object
bitfieldA {.bitsize: 16.}: uint32
bitfieldB {.bitsize: 16.}: uint32
var wbs: WithBitsize
testSize(wbs)
testOffsetOf(TrivialType, x)
testOffsetOf(TrivialType, y)
testOffsetOf(TrivialType, z)
@@ -308,6 +332,7 @@ testinstance:
testOffsetOf(SimpleAlignment, a)
testOffsetOf(SimpleAlignment, b)
testOffsetOf(SimpleAlignment, c)
testOffsetOf(AlignAtEnd, a)
testOffsetOf(AlignAtEnd, b)
testOffsetOf(AlignAtEnd, c)
@@ -369,4 +394,7 @@ type
assert sizeof(Bar) == 12
echo "OK"
if failed:
quit("FAIL")
else:
echo "OK"