#63490 closed defect (fixed)
libdazzle @3.38.0_0: Static assert failure on PowerPC due to struct packing issue with different version of gcc
Reported by: | evanmiller (Evan Miller) | Owned by: | evanmiller (Evan Miller) |
---|---|---|---|
Priority: | Normal | Milestone: | |
Component: | ports | Version: | 2.7.1 |
Keywords: | Cc: | kencu (Ken) | |
Port: | libdazzle |
Description
:info:build In file included from /opt/local/lib/glib-2.0/include/glibconfig.h:9:0, :info:build from /opt/local/include/glib-2.0/glib/gtypes.h:32, :info:build from /opt/local/include/glib-2.0/glib/galloca.h:32, :info:build from /opt/local/include/glib-2.0/glib.h:30, :info:build from /opt/local/include/glib-2.0/gobject/gbinding.h:28, :info:build from /opt/local/include/glib-2.0/glib-object.h:23, :info:build from ../libdazzle-3.38.0/src/search/dzl-fuzzy-mutable-index.h:22, :info:build from ../libdazzle-3.38.0/src/search/dzl-fuzzy-mutable-index.c:24: :info:build /opt/local/include/glib-2.0/glib/gmacros.h:738:31: error: static assertion failed: "Expression evaluates to false" :info:build #define G_STATIC_ASSERT(expr) _Static_assert (expr, "Expression evaluates to false") :info:build ^ :info:build ../libdazzle-3.38.0/src/search/dzl-fuzzy-mutable-index.c:70:1: note: in expansion of macro 'G_STATIC_ASSERT' :info:build G_STATIC_ASSERT (sizeof(DzlFuzzyMutableIndexItem) == 6); :info:build ^~~~~~~~~~~~~~~ :info:build ninja: build stopped: subcommand failed.
Context:
#pragma pack(push, 1) typedef struct { guint64 id : 32; guint64 pos : 16; } DzlFuzzyMutableIndexItem; #pragma pack(pop)
In a test program, the above structure is 8 bytes but libdazzle is expecting it to be 6 bytes.
sysinfo
:debug:sysinfo Mac OS X 10.4.11 (darwin/8.11.0) arch powerpc :debug:sysinfo MacPorts 2.7.1 :debug:sysinfo Xcode 2.5 :debug:sysinfo SDK 10.4 :debug:sysinfo MACOSX_DEPLOYMENT_TARGET: 10.4
Full log to follow.
Attachments (1)
Change History (15)
Changed 3 years ago by evanmiller (Evan Miller)
Attachment: | libdazzle-main.log added |
---|
comment:1 Changed 3 years ago by kencu (Ken)
comment:2 Changed 3 years ago by evanmiller (Evan Miller)
Thanks for the link. I'm still confused why there are 2 bytes of end padding with pack(push, 1)
in place. Perhaps this is controlled by a separate pragma or flag.
comment:3 Changed 3 years ago by kencu (Ken)
how does this work, exactly?
guint64 pos : 16;
If a guint64 needs 4 bytes, how does adding the " : 16" somehow make it a two-byter?
I haven't seen this construct much before, or at least haven't noticed it...
comment:4 Changed 3 years ago by evanmiller (Evan Miller)
These are bit fields https://docs.microsoft.com/en-us/cpp/c-language/c-bit-fields?view=msvc-160
comment:5 Changed 3 years ago by evanmiller (Evan Miller)
Well, it looks like libdazzle has updated this code for Win32:
https://gitlab.gnome.org/GNOME/libdazzle/-/blob/master/src/search/dzl-fuzzy-mutable-index.c#L62-75
Likely we'll need to include PPC in that ifdef or patch similarly
comment:6 Changed 3 years ago by evanmiller (Evan Miller)
Actually, the Win32 code doesn't solve the problem on PPC, so further research is needed.
comment:7 Changed 3 years ago by kencu (Ken)
interesting:
$ cat packcheck.c #include <stdio.h> #include <stdint.h> int main(void) { #pragma option align=mac68k typedef struct { uint32_t id : 32; uint32_t pos : 16; } KenStruct; KenStruct mystruct; printf("%i\n\n", sizeof(KenStruct)); return 0; }
$ gcc-mp-7 packcheck.c $ ./a.out 8
$ gcc-apple-4.2 packcheck.c $ ./a.out 8
$ gcc-apple-4.2 -malign-mac68k packcheck.c $ ./a.out 6
comment:8 Changed 3 years ago by evanmiller (Evan Miller)
Interestingly, just the regular pack directives work as expected with gcc-apple-4.2:
#include <stdint.h> #pragma pack(push, 1) typedef struct { uint32_t id; uint16_t pos; } DzlFuzzyMutableIndexItem; #pragma pack(pop) int main() { return sizeof(DzlFuzzyMutableIndexItem); }
$ gcc-mp-7 test-pack.c && ./a.out $ echo $? 8 $ gcc-apple-4.2 test-pack.c && ./a.out $ echo $? 6
So the struct-padding algorithm changed at some point.
comment:9 Changed 3 years ago by kencu (Ken)
This works properly:
$ cat packcheck.c #include <stdio.h> #include <stdint.h> int main(void) { typedef struct __attribute__((packed)) { uint32_t id : 32; uint16_t pos : 16; } KenStruct; KenStruct mystruct; printf("%i\n\n", sizeof(KenStruct)); return 0; }
$ gcc-mp-7 packcheck.c $ ./a.out 6
comment:10 Changed 3 years ago by kencu (Ken)
and back to the original, looks pretty good:
$ cat packcheck.c #include <stdio.h> #include <glib.h> int main(void) { typedef struct __attribute__((packed)) { guint64 id : 32; guint64 pos : 16; } KenStruct; KenStruct mystruct; printf("%i\n\n", sizeof(KenStruct)); return 0; }
$ gcc-mp-7 `pkg-config --cflags glib-2.0` packcheck.c $ ./a.out 6
so that looks like our solution.
comment:11 follow-up: 14 Changed 3 years ago by evanmiller (Evan Miller)
Nice find! Wonder whether that's a GCC bug and whether GCC11 has the same behavior.
Anyway, we have a workaround now. I'll get a patch going, assuming everything else compiles OK.
comment:12 Changed 3 years ago by evanmiller (Evan Miller)
Owner: | set to evanmiller |
---|---|
Resolution: | → fixed |
Status: | new → closed |
comment:13 Changed 18 months ago by kencu (Ken)
Summary: | libdazzle @3.38.0_0: Static assert failure on PowerPC → libdazzle @3.38.0_0: Static assert failure on PowerPC due to struct packing issue with different version of gcc |
---|
comment:14 Changed 18 months ago by barracuda156
Replying to evanmiller:
Nice find! Wonder whether that's a GCC bug and whether GCC11 has the same behavior.
Anyway, we have a workaround now. I'll get a patch going, assuming everything else compiles OK.
Yes, as well as GCC12: https://github.com/macports/macports-ports/pull/18872#issuecomment-1568714259
useful:
http://personal.denison.edu/~bressoud/cs281-s07/MacOSXLowLevelABI.pdf