diff options
-rw-r--r-- | compiler/ccgtypes.nim | 27 | ||||
-rw-r--r-- | compiler/extccomp.nim | 4 | ||||
-rw-r--r-- | config/nim.cfg | 3 | ||||
-rw-r--r-- | tests/objects/tobject3.nim | 32 |
4 files changed, 55 insertions, 11 deletions
diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim index 0c81ca814..aba9c5342 100644 --- a/compiler/ccgtypes.nim +++ b/compiler/ccgtypes.nim @@ -473,11 +473,14 @@ proc genRecordFieldsAux(m: BModule, n: PNode, if tfPacked notin rectype.flags: add(unionBody, "struct {") else: - addf(unionBody, CC[cCompiler].structStmtFmt, - [rope"struct", nil, rope(CC[cCompiler].packedPragma)]) - add(unionBody, "{") + if hasAttribute in CC[cCompiler].props: + add(unionBody, "struct __attribute__((__packed__)){" ) + else: + addf(unionBody, "#pragma pack(1)$nstruct{", []) add(unionBody, a) addf(unionBody, "} $1;$n", [sname]) + if tfPacked in rectype.flags and hasAttribute notin CC[cCompiler].props: + addf(unionBody, "#pragma pack(pop)$n", []) else: add(unionBody, genRecordFieldsAux(m, k, ae, rectype, check)) else: internalError("genRecordFieldsAux(record case branch)") @@ -524,12 +527,16 @@ proc getRecordDesc(m: BModule, typ: PType, name: Rope, # declare the record: var hasField = false - var attribute: Rope = - if tfPacked in typ.flags: rope(CC[cCompiler].packedPragma) - else: nil + if tfPacked in typ.flags: + if hasAttribute in CC[cCompiler].props: + result = structOrUnion(typ) & " __attribute__((__packed__))" + else: + result = "#pragma pack(1)" & tnl & structOrUnion(typ) + else: + result = structOrUnion(typ) - result = ropecg(m, CC[cCompiler].structStmtFmt, - [structOrUnion(typ), name, attribute]) + result.add " " + result.add name if typ.kind == tyObject: @@ -537,7 +544,7 @@ proc getRecordDesc(m: BModule, typ: PType, name: Rope, if (typ.sym != nil and sfPure in typ.sym.flags) or tfFinal in typ.flags: appcg(m, result, " {$n", []) else: - appcg(m, result, " {$n#TNimType* m_type;$n", [name, attribute]) + appcg(m, result, " {$n#TNimType* m_type;$n", []) hasField = true elif m.compileToCpp: appcg(m, result, " : public $1 {$n", @@ -556,6 +563,8 @@ proc getRecordDesc(m: BModule, typ: PType, name: Rope, else: add(result, desc) add(result, "};" & tnl) + if tfPacked in typ.flags and hasAttribute notin CC[cCompiler].props: + result.add "#pragma pack(pop)" & tnl proc getTupleDesc(m: BModule, typ: PType, name: Rope, check: var IntSet): Rope = diff --git a/compiler/extccomp.nim b/compiler/extccomp.nim index ca4f621e4..db6de3f26 100644 --- a/compiler/extccomp.nim +++ b/compiler/extccomp.nim @@ -129,7 +129,7 @@ compiler vcc: pic: "", asmStmtFrmt: "__asm{$n$1$n}$n", structStmtFmt: "$3$n$1 $2", - packedPragma: "#pragma pack(1)", + packedPragma: "#pragma pack(1)$n$1$n#pragma pack(pop)$n", props: {hasCpp, hasAssume, hasDeclspec}) # Intel C/C++ Compiler @@ -216,7 +216,7 @@ compiler dmc: pic: "", asmStmtFrmt: "__asm{$n$1$n}$n", structStmtFmt: "$3$n$1 $2", - packedPragma: "#pragma pack(1)", + packedPragma: "#pragma pack(1)$n$1$n#pragma pack(pop)$n", props: {hasCpp}) # Watcom C Compiler diff --git a/config/nim.cfg b/config/nim.cfg index 9374e2b88..291d2a3bc 100644 --- a/config/nim.cfg +++ b/config/nim.cfg @@ -109,6 +109,9 @@ path="$lib/pure" tlsEmulation:on gcc.options.always = "-w" gcc.cpp.options.always = "-w -fpermissive" +@elif windows: + gcc.options.always = "-w -mno-ms-bitfields" + gcc.cpp.options.always = "-w -fpermissive -mno-ms-bitfields" @else: gcc.options.always = "-w" gcc.cpp.options.always = "-w -fpermissive" diff --git a/tests/objects/tobject3.nim b/tests/objects/tobject3.nim index 15dd8ea24..f3713ce22 100644 --- a/tests/objects/tobject3.nim +++ b/tests/objects/tobject3.nim @@ -1,3 +1,13 @@ +discard """ + ouptut: '''TBar2 +TFoo +16 +12 +16 +12''' +""" + +## XXX this output needs to be adapated for VCC which produces different results. # It turned out that it's hard to generate correct for these two test cases at # the same time. @@ -57,3 +67,25 @@ var aa = makeWindow() thisCausesError(dd, aa) +# bug #4763 +type + testObject_1 = object + size: int32 + value: int64 + + testObject_2 {.packed.} = object + size: int32 + value: int64 + + testObject_3[T] = object + size: int32 + value: T + + testObject_4 {.packed.} [T] = object + size: int32 + value: T + +echo sizeof(testObject_1) +echo sizeof(testObject_2) +echo sizeof(testObject_3[int64]) +echo sizeof(testObject_4[int64]) |