diff options
author | Clyybber <darkmine956@gmail.com> | 2020-07-01 11:41:03 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-07-01 11:41:03 +0200 |
commit | 1440e70c62e7dc2e2a2062c1291f65c12055818a (patch) | |
tree | d7ba6ef283ac73af016fb404e62fe801a2959de5 /compiler | |
parent | 1edb9a6178d868e34e76faf9e2a05afbc1431cb0 (diff) | |
download | Nim-1440e70c62e7dc2e2a2062c1291f65c12055818a.tar.gz |
allow packed union (#14868)
Co-authored-by: Arne Döring <arne.doering@gmx.net>
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/sizealignoffsetimpl.nim | 16 |
1 files changed, 7 insertions, 9 deletions
diff --git a/compiler/sizealignoffsetimpl.nim b/compiler/sizealignoffsetimpl.nim index 4d73923db..baa2c40f9 100644 --- a/compiler/sizealignoffsetimpl.nim +++ b/compiler/sizealignoffsetimpl.nim @@ -164,7 +164,7 @@ proc computeObjectOffsetsFoldFunction(conf: ConfigRef; n: PNode, packed: bool, a accum.maxAlign = szUnknownSize accum.offset = szUnknownSize -proc computeUnionObjectOffsetsFoldFunction(conf: ConfigRef; n: PNode; accum: var OffsetAccum) = +proc computeUnionObjectOffsetsFoldFunction(conf: ConfigRef; n: PNode; packed: bool; accum: var OffsetAccum) = ## ``accum.offset`` will the offset from the larget member of the union. case n.kind of nkRecCase: @@ -175,7 +175,7 @@ proc computeUnionObjectOffsetsFoldFunction(conf: ConfigRef; n: PNode; accum: var let accumRoot = accum # copy, because each branch should start af the same offset for i, child in n.sons: var branchAccum = accumRoot - computeUnionObjectOffsetsFoldFunction(conf, child, branchAccum) + computeUnionObjectOffsetsFoldFunction(conf, child, packed, branchAccum) accum.mergeBranch(branchAccum) of nkSym: var size = szUnknownSize @@ -183,7 +183,7 @@ proc computeUnionObjectOffsetsFoldFunction(conf: ConfigRef; n: PNode; accum: var 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 + align = if packed: 1 else: n.sym.typ.align.int accum.align(align) if n.sym.alignment > 0: accum.align(n.sym.alignment) @@ -365,16 +365,14 @@ proc computeSizeAlign(conf: ConfigRef; typ: PType) = else: OffsetAccum(maxAlign: 1) if tfUnion in typ.flags: - if tfPacked in typ.flags: - let info = if typ.sym != nil: typ.sym.info else: unknownLineInfo - localError(conf, info, "union type may not be packed.") - accum = OffsetAccum(offset: szUnknownSize, maxAlign: szUnknownSize) - elif accum.offset != 0: + if accum.offset != 0: let info = if typ.sym != nil: typ.sym.info else: unknownLineInfo localError(conf, info, "union type may not have an object header") accum = OffsetAccum(offset: szUnknownSize, maxAlign: szUnknownSize) + elif tfPacked in typ.flags: + computeUnionObjectOffsetsFoldFunction(conf, typ.n, true, accum) else: - computeUnionObjectOffsetsFoldFunction(conf, typ.n, accum) + computeUnionObjectOffsetsFoldFunction(conf, typ.n, false, accum) elif tfPacked in typ.flags: accum.maxAlign = 1 computeObjectOffsetsFoldFunction(conf, typ.n, true, accum) |