summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/ccgtypes.nim27
-rw-r--r--compiler/extccomp.nim4
-rw-r--r--config/nim.cfg3
-rw-r--r--tests/objects/tobject3.nim32
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])