This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug c/51628] __attribute__((packed)) is unsafe in some cases
- From: "hjl.tools at gmail dot com" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Wed, 17 Jan 2018 13:37:44 +0000
- Subject: [Bug c/51628] __attribute__((packed)) is unsafe in some cases
- Auto-submitted: auto-generated
- References: <bug-51628-4@http.gcc.gnu.org/bugzilla/>
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51628
--- Comment #45 from H.J. Lu <hjl.tools at gmail dot com> ---
(In reply to Sven from comment #44)
>
> You can combine the packed attribute with the aligned attribute. Then you
> can define one struct with aligned(4) and one with aligned(8). Does the
> warning trigger if you cast between those types? Or does the cast simply
> override the warning because it's now the programmers responsibility to make
> sure that the alignment is correct?
Yes, my patch handles it correctly:
[hjl@gnu-tools-1 pr51628]$ cat g3.i
struct pair_t {
__int128_t x;
__int128_t i;
} __attribute__((packed, aligned (4)));
typedef struct unaligned_int128_t_ {
__int128_t value;
} __attribute__((packed, aligned (8))) unaligned_int128_t;
struct pair_t p = {0, 1};
unaligned_int128_t *addr = (unaligned_int128_t *)(&p.i);
int main() {
addr->value = ~(__int128_t)0;
return (p.i != 1) ? 0 : 1;
}
[hjl@gnu-tools-1 pr51628]$
/export/build/gnu/gcc-test/build-x86_64-linux/gcc/xgcc
-B/export/build/gnu/gcc-test/build-x86_64-linux/gcc/ -O2 -S g3.i
g3.i:11:28: warning: initialization of ‘unaligned_int128_t *’ {aka ‘struct
unaligned_int128_t_ *’} from address of packed member of ‘struct pair_t’ may
result in an unaligned pointer value [-Waddress-of-packed-member]
unaligned_int128_t *addr = (unaligned_int128_t *)(&p.i);
^
[hjl@gnu-tools-1 pr51628]$ cat g4.i
struct pair_t {
__int128_t x;
__int128_t i;
} __attribute__((packed, aligned (8)));
typedef struct unaligned_int128_t_ {
__int128_t value;
} __attribute__((packed, aligned (4))) unaligned_int128_t;
struct pair_t p = {0, 1};
unaligned_int128_t *addr = (unaligned_int128_t *)(&p.i);
int main() {
addr->value = ~(__int128_t)0;
return (p.i != 1) ? 0 : 1;
}
[hjl@gnu-tools-1 pr51628]$
/export/build/gnu/gcc-test/build-x86_64-linux/gcc/xgcc
-B/export/build/gnu/gcc-test/build-x86_64-linux/gcc/ -O2 -S g4.i
[hjl@gnu-tools-1 pr51628]$