bitsize respected in size calculation. (#9756)
This commit is contained in:
parent
2418d0cac5
commit
1e08fff2d5
3 changed files with 42 additions and 7 deletions
|
|
@ -1062,6 +1062,8 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int,
|
||||||
invalidPragma(c, it)
|
invalidPragma(c, it)
|
||||||
else:
|
else:
|
||||||
sym.bitsize = expectIntLit(c, it)
|
sym.bitsize = expectIntLit(c, it)
|
||||||
|
if sym.bitsize <= 0:
|
||||||
|
localError(c.config, it.info, "bitsize needs to be positive")
|
||||||
of wGuard:
|
of wGuard:
|
||||||
if sym == nil or sym.kind notin {skVar, skLet, skField}:
|
if sym == nil or sym.kind notin {skVar, skLet, skField}:
|
||||||
invalidPragma(c, it)
|
invalidPragma(c, it)
|
||||||
|
|
|
||||||
|
|
@ -127,9 +127,14 @@ proc computeObjectOffsetsFoldFunction(conf: ConfigRef; n: PNode, initialOffset:
|
||||||
result.offset = align(offset, result.align)
|
result.offset = align(offset, result.align)
|
||||||
|
|
||||||
of nkSym:
|
of nkSym:
|
||||||
computeSizeAlign(conf, n.sym.typ)
|
var size = szUnknownSize
|
||||||
let size = n.sym.typ.size
|
var align = szUnknownSize
|
||||||
let align = n.sym.typ.align
|
|
||||||
|
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
|
result.align = align
|
||||||
if initialOffset == szUnknownSize or size == szUnknownSize:
|
if initialOffset == szUnknownSize or size == szUnknownSize:
|
||||||
n.sym.offset = szUnknownSize
|
n.sym.offset = szUnknownSize
|
||||||
|
|
|
||||||
|
|
@ -10,14 +10,16 @@ type
|
||||||
TMyArray2 = array[1..3, int32]
|
TMyArray2 = array[1..3, int32]
|
||||||
TMyArray3 = array[TMyEnum, float64]
|
TMyArray3 = array[TMyEnum, float64]
|
||||||
|
|
||||||
|
var failed = false
|
||||||
|
|
||||||
const
|
const
|
||||||
mysize1 = sizeof(TMyArray1)
|
mysize1 = sizeof(TMyArray1)
|
||||||
mysize2 = sizeof(TMyArray2)
|
mysize2 = sizeof(TMyArray2)
|
||||||
mysize3 = sizeof(TMyArray3)
|
mysize3 = sizeof(TMyArray3)
|
||||||
|
|
||||||
assert mysize1 == 3
|
doAssert mysize1 == 3
|
||||||
assert mysize2 == 12
|
doAssert mysize2 == 12
|
||||||
assert mysize3 == 32
|
doAssert mysize3 == 32
|
||||||
|
|
||||||
import macros, typetraits
|
import macros, typetraits
|
||||||
|
|
||||||
|
|
@ -38,6 +40,7 @@ macro testSizeAlignOf(args: varargs[untyped]): untyped =
|
||||||
if nim_align != c_align:
|
if nim_align != c_align:
|
||||||
msg.add " align(get, expected): " & $nim_align & " != " & $c_align
|
msg.add " align(get, expected): " & $nim_align & " != " & $c_align
|
||||||
echo msg
|
echo msg
|
||||||
|
failed = true
|
||||||
|
|
||||||
|
|
||||||
macro testOffsetOf(a,b1,b2: untyped): untyped =
|
macro testOffsetOf(a,b1,b2: untyped): untyped =
|
||||||
|
|
@ -49,6 +52,7 @@ macro testOffsetOf(a,b1,b2: untyped): untyped =
|
||||||
nim_offset = offsetof(`a`,`b2`)
|
nim_offset = offsetof(`a`,`b2`)
|
||||||
if c_offset != nim_offset:
|
if c_offset != nim_offset:
|
||||||
echo `typeName`, ".", `member`, " offsetError, C: ", c_offset, " nim: ", nim_offset
|
echo `typeName`, ".", `member`, " offsetError, C: ", c_offset, " nim: ", nim_offset
|
||||||
|
failed = true
|
||||||
|
|
||||||
template testOffsetOf(a,b: untyped): untyped =
|
template testOffsetOf(a,b: untyped): untyped =
|
||||||
testOffsetOf(a,b,b)
|
testOffsetOf(a,b,b)
|
||||||
|
|
@ -100,6 +104,16 @@ macro testAlign(arg:untyped):untyped =
|
||||||
let nimAlign = alignof(`arg`)
|
let nimAlign = alignof(`arg`)
|
||||||
if cAlign != nimAlign:
|
if cAlign != nimAlign:
|
||||||
echo `prefix`, 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
|
type
|
||||||
MyEnum {.pure.} = enum
|
MyEnum {.pure.} = enum
|
||||||
|
|
@ -297,10 +311,20 @@ testinstance:
|
||||||
eoa: EnumObjectA
|
eoa: EnumObjectA
|
||||||
eob: EnumObjectB
|
eob: EnumObjectB
|
||||||
|
|
||||||
|
|
||||||
testAlign(SimpleAlignment)
|
testAlign(SimpleAlignment)
|
||||||
|
|
||||||
testSizeAlignOf(t,a,b,c,d,e,f,g,ro, e1, e2, e4, e8, eoa, eob)
|
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, x)
|
||||||
testOffsetOf(TrivialType, y)
|
testOffsetOf(TrivialType, y)
|
||||||
testOffsetOf(TrivialType, z)
|
testOffsetOf(TrivialType, z)
|
||||||
|
|
@ -308,6 +332,7 @@ testinstance:
|
||||||
testOffsetOf(SimpleAlignment, a)
|
testOffsetOf(SimpleAlignment, a)
|
||||||
testOffsetOf(SimpleAlignment, b)
|
testOffsetOf(SimpleAlignment, b)
|
||||||
testOffsetOf(SimpleAlignment, c)
|
testOffsetOf(SimpleAlignment, c)
|
||||||
|
|
||||||
testOffsetOf(AlignAtEnd, a)
|
testOffsetOf(AlignAtEnd, a)
|
||||||
testOffsetOf(AlignAtEnd, b)
|
testOffsetOf(AlignAtEnd, b)
|
||||||
testOffsetOf(AlignAtEnd, c)
|
testOffsetOf(AlignAtEnd, c)
|
||||||
|
|
@ -369,4 +394,7 @@ type
|
||||||
|
|
||||||
assert sizeof(Bar) == 12
|
assert sizeof(Bar) == 12
|
||||||
|
|
||||||
echo "OK"
|
if failed:
|
||||||
|
quit("FAIL")
|
||||||
|
else:
|
||||||
|
echo "OK"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue