This commit is contained in:
Araq 2017-07-17 09:28:03 +02:00
commit 91eba77b96
4 changed files with 55 additions and 11 deletions

View file

@ -473,11 +473,14 @@ proc genRecordFieldsAux(m: BModule, n: PNode,
if tfPacked notin rectype.flags: if tfPacked notin rectype.flags:
add(unionBody, "struct {") add(unionBody, "struct {")
else: else:
addf(unionBody, CC[cCompiler].structStmtFmt, if hasAttribute in CC[cCompiler].props:
[rope"struct", nil, rope(CC[cCompiler].packedPragma)]) add(unionBody, "struct __attribute__((__packed__)){" )
add(unionBody, "{") else:
addf(unionBody, "#pragma pack(1)$nstruct{", [])
add(unionBody, a) add(unionBody, a)
addf(unionBody, "} $1;$n", [sname]) addf(unionBody, "} $1;$n", [sname])
if tfPacked in rectype.flags and hasAttribute notin CC[cCompiler].props:
addf(unionBody, "#pragma pack(pop)$n", [])
else: else:
add(unionBody, genRecordFieldsAux(m, k, ae, rectype, check)) add(unionBody, genRecordFieldsAux(m, k, ae, rectype, check))
else: internalError("genRecordFieldsAux(record case branch)") else: internalError("genRecordFieldsAux(record case branch)")
@ -524,12 +527,16 @@ proc getRecordDesc(m: BModule, typ: PType, name: Rope,
# declare the record: # declare the record:
var hasField = false var hasField = false
var attribute: Rope = if tfPacked in typ.flags:
if tfPacked in typ.flags: rope(CC[cCompiler].packedPragma) if hasAttribute in CC[cCompiler].props:
else: nil result = structOrUnion(typ) & " __attribute__((__packed__))"
else:
result = "#pragma pack(1)" & tnl & structOrUnion(typ)
else:
result = structOrUnion(typ)
result = ropecg(m, CC[cCompiler].structStmtFmt, result.add " "
[structOrUnion(typ), name, attribute]) result.add name
if typ.kind == tyObject: 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: if (typ.sym != nil and sfPure in typ.sym.flags) or tfFinal in typ.flags:
appcg(m, result, " {$n", []) appcg(m, result, " {$n", [])
else: else:
appcg(m, result, " {$n#TNimType* m_type;$n", [name, attribute]) appcg(m, result, " {$n#TNimType* m_type;$n", [])
hasField = true hasField = true
elif m.compileToCpp: elif m.compileToCpp:
appcg(m, result, " : public $1 {$n", appcg(m, result, " : public $1 {$n",
@ -556,6 +563,8 @@ proc getRecordDesc(m: BModule, typ: PType, name: Rope,
else: else:
add(result, desc) add(result, desc)
add(result, "};" & tnl) 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, proc getTupleDesc(m: BModule, typ: PType, name: Rope,
check: var IntSet): Rope = check: var IntSet): Rope =

View file

@ -129,7 +129,7 @@ compiler vcc:
pic: "", pic: "",
asmStmtFrmt: "__asm{$n$1$n}$n", asmStmtFrmt: "__asm{$n$1$n}$n",
structStmtFmt: "$3$n$1 $2", structStmtFmt: "$3$n$1 $2",
packedPragma: "#pragma pack(1)", packedPragma: "#pragma pack(1)$n$1$n#pragma pack(pop)$n",
props: {hasCpp, hasAssume, hasDeclspec}) props: {hasCpp, hasAssume, hasDeclspec})
# Intel C/C++ Compiler # Intel C/C++ Compiler
@ -216,7 +216,7 @@ compiler dmc:
pic: "", pic: "",
asmStmtFrmt: "__asm{$n$1$n}$n", asmStmtFrmt: "__asm{$n$1$n}$n",
structStmtFmt: "$3$n$1 $2", structStmtFmt: "$3$n$1 $2",
packedPragma: "#pragma pack(1)", packedPragma: "#pragma pack(1)$n$1$n#pragma pack(pop)$n",
props: {hasCpp}) props: {hasCpp})
# Watcom C Compiler # Watcom C Compiler

View file

@ -109,6 +109,9 @@ path="$lib/pure"
tlsEmulation:on tlsEmulation:on
gcc.options.always = "-w" gcc.options.always = "-w"
gcc.cpp.options.always = "-w -fpermissive" 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: @else:
gcc.options.always = "-w" gcc.options.always = "-w"
gcc.cpp.options.always = "-w -fpermissive" gcc.cpp.options.always = "-w -fpermissive"

View file

@ -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 # It turned out that it's hard to generate correct for these two test cases at
# the same time. # the same time.
@ -57,3 +67,25 @@ var aa = makeWindow()
thisCausesError(dd, aa) 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])