2009-12-16 04:14:24 +08:00
|
|
|
// RUN: %clang_cc1 %s -fsyntax-only -verify
|
2015-12-03 17:34:49 +08:00
|
|
|
// RUN: %clang_cc1 %s -fsyntax-only -triple=x86_64-windows-coff -verify
|
2008-02-16 09:20:23 +08:00
|
|
|
|
2008-02-17 03:51:36 +08:00
|
|
|
// Packed structs.
|
2008-02-16 09:20:23 +08:00
|
|
|
struct s {
|
|
|
|
char a;
|
|
|
|
int b __attribute__((packed));
|
|
|
|
char c;
|
|
|
|
int d;
|
|
|
|
};
|
|
|
|
|
2008-02-17 03:51:36 +08:00
|
|
|
extern int a1[sizeof(struct s) == 12 ? 1 : -1];
|
|
|
|
extern int a2[__alignof(struct s) == 4 ? 1 : -1];
|
|
|
|
|
2008-02-16 09:20:23 +08:00
|
|
|
struct __attribute__((packed)) packed_s {
|
|
|
|
char a;
|
|
|
|
int b __attribute__((packed));
|
|
|
|
char c;
|
|
|
|
int d;
|
|
|
|
};
|
|
|
|
|
2008-02-17 03:51:36 +08:00
|
|
|
extern int b1[sizeof(struct packed_s) == 10 ? 1 : -1];
|
|
|
|
extern int b2[__alignof(struct packed_s) == 1 ? 1 : -1];
|
|
|
|
|
2008-02-16 09:20:23 +08:00
|
|
|
struct fas {
|
|
|
|
char a;
|
|
|
|
int b[];
|
|
|
|
};
|
|
|
|
|
2008-02-17 03:51:36 +08:00
|
|
|
extern int c1[sizeof(struct fas) == 4 ? 1 : -1];
|
|
|
|
extern int c2[__alignof(struct fas) == 4 ? 1 : -1];
|
|
|
|
|
2008-02-16 09:20:23 +08:00
|
|
|
struct __attribute__((packed)) packed_fas {
|
|
|
|
char a;
|
|
|
|
int b[];
|
|
|
|
};
|
|
|
|
|
2008-02-17 03:51:36 +08:00
|
|
|
extern int d1[sizeof(struct packed_fas) == 1 ? 1 : -1];
|
|
|
|
extern int d2[__alignof(struct packed_fas) == 1 ? 1 : -1];
|
2008-02-16 09:20:23 +08:00
|
|
|
|
2010-03-29 22:42:08 +08:00
|
|
|
struct packed_after_fas {
|
|
|
|
char a;
|
|
|
|
int b[];
|
|
|
|
} __attribute__((packed));
|
|
|
|
|
|
|
|
extern int d1_2[sizeof(struct packed_after_fas) == 1 ? 1 : -1];
|
|
|
|
extern int d2_2[__alignof(struct packed_after_fas) == 1 ? 1 : -1];
|
|
|
|
|
2008-02-17 03:51:36 +08:00
|
|
|
// Alignment
|
2008-02-16 09:20:23 +08:00
|
|
|
|
2008-02-17 03:51:36 +08:00
|
|
|
struct __attribute__((aligned(8))) as1 {
|
|
|
|
char c;
|
|
|
|
};
|
2008-02-16 09:20:23 +08:00
|
|
|
|
2008-02-17 03:51:36 +08:00
|
|
|
extern int e1[sizeof(struct as1) == 8 ? 1 : -1];
|
|
|
|
extern int e2[__alignof(struct as1) == 8 ? 1 : -1];
|
|
|
|
|
2009-02-19 04:06:09 +08:00
|
|
|
struct __attribute__((aligned)) as1_2 {
|
|
|
|
char c;
|
|
|
|
};
|
Implement target-specific __attribute__((aligned)) value
The GCC construct __attribute__((aligned)) is defined to set alignment
to "the default alignment for the target architecture" according to
the GCC documentation:
The default alignment is sufficient for all scalar types, but may not be
enough for all vector types on a target that supports vector operations.
The default alignment is fixed for a particular target ABI.
clang currently hard-coded an alignment of 16 bytes for that construct,
which is correct on some platforms (including X86), but wrong on others
(including SystemZ). Since this value is ABI-relevant, it is important
to get correct for compatibility purposes.
This patch adds a new TargetInfo member "DefaultAlignForAttributeAligned"
that targets can set to the appropriate default __attribute__((aligned))
value.
Note that I'm deliberately *not* using the existing "SuitableAlign"
value, which is used to set the pre-defined macro __BIGGEST_ALIGNMENT__,
since those two values may not be the same on all platforms. In fact,
on X86, __attribute__((aligned)) always uses 16-byte alignment, while
__BIGGEST_ALIGNMENT__ may be larger if AVX-2 or AVX-512 are supported.
(This is actually not yet correctly implemented in clang either.)
The patch provides a value for DefaultAlignForAttributeAligned only for
SystemZ, and leaves the default for all other targets at 16, which means
no visible change in behavior on all other targets. (The value is still
wrong for some other targets, but I'd prefer to leave it to the target
maintainers for those platforms to fix.)
llvm-svn: 235397
2015-04-22 01:29:35 +08:00
|
|
|
#ifdef __s390x__
|
|
|
|
extern int e1_2[sizeof(struct as1_2) == 8 ? 1 : -1];
|
|
|
|
extern int e2_2[__alignof(struct as1_2) == 8 ? 1 : -1];
|
|
|
|
#else
|
2009-02-19 04:06:09 +08:00
|
|
|
extern int e1_2[sizeof(struct as1_2) == 16 ? 1 : -1];
|
|
|
|
extern int e2_2[__alignof(struct as1_2) == 16 ? 1 : -1];
|
Implement target-specific __attribute__((aligned)) value
The GCC construct __attribute__((aligned)) is defined to set alignment
to "the default alignment for the target architecture" according to
the GCC documentation:
The default alignment is sufficient for all scalar types, but may not be
enough for all vector types on a target that supports vector operations.
The default alignment is fixed for a particular target ABI.
clang currently hard-coded an alignment of 16 bytes for that construct,
which is correct on some platforms (including X86), but wrong on others
(including SystemZ). Since this value is ABI-relevant, it is important
to get correct for compatibility purposes.
This patch adds a new TargetInfo member "DefaultAlignForAttributeAligned"
that targets can set to the appropriate default __attribute__((aligned))
value.
Note that I'm deliberately *not* using the existing "SuitableAlign"
value, which is used to set the pre-defined macro __BIGGEST_ALIGNMENT__,
since those two values may not be the same on all platforms. In fact,
on X86, __attribute__((aligned)) always uses 16-byte alignment, while
__BIGGEST_ALIGNMENT__ may be larger if AVX-2 or AVX-512 are supported.
(This is actually not yet correctly implemented in clang either.)
The patch provides a value for DefaultAlignForAttributeAligned only for
SystemZ, and leaves the default for all other targets at 16, which means
no visible change in behavior on all other targets. (The value is still
wrong for some other targets, but I'd prefer to leave it to the target
maintainers for those platforms to fix.)
llvm-svn: 235397
2015-04-22 01:29:35 +08:00
|
|
|
#endif
|
2009-02-19 04:06:09 +08:00
|
|
|
|
2008-02-17 03:51:36 +08:00
|
|
|
struct as2 {
|
|
|
|
char c;
|
|
|
|
int __attribute__((aligned(8))) a;
|
|
|
|
};
|
|
|
|
|
|
|
|
extern int f1[sizeof(struct as2) == 16 ? 1 : -1];
|
|
|
|
extern int f2[__alignof(struct as2) == 8 ? 1 : -1];
|
|
|
|
|
|
|
|
struct __attribute__((packed)) as3 {
|
|
|
|
char c;
|
|
|
|
int a;
|
|
|
|
int __attribute__((aligned(8))) b;
|
|
|
|
};
|
|
|
|
|
|
|
|
extern int g1[sizeof(struct as3) == 16 ? 1 : -1];
|
|
|
|
extern int g2[__alignof(struct as3) == 8 ? 1 : -1];
|
2008-05-09 13:34:49 +08:00
|
|
|
|
|
|
|
|
|
|
|
// rdar://5921025
|
|
|
|
struct packedtest {
|
|
|
|
int ted_likes_cheese;
|
|
|
|
void *args[] __attribute__((packed));
|
|
|
|
};
|
2008-05-30 17:31:38 +08:00
|
|
|
|
|
|
|
// Packed union
|
|
|
|
union __attribute__((packed)) au4 {char c; int x;};
|
|
|
|
extern int h1[sizeof(union au4) == 4 ? 1 : -1];
|
|
|
|
extern int h2[__alignof(union au4) == 1 ? 1 : -1];
|
|
|
|
|
|
|
|
// Aligned union
|
|
|
|
union au5 {__attribute__((aligned(4))) char c;};
|
|
|
|
extern int h1[sizeof(union au5) == 4 ? 1 : -1];
|
|
|
|
extern int h2[__alignof(union au5) == 4 ? 1 : -1];
|
|
|
|
|
|
|
|
// Alignment+packed
|
|
|
|
struct as6 {char c; __attribute__((packed, aligned(2))) int x;};
|
|
|
|
extern int i1[sizeof(struct as6) == 6 ? 1 : -1];
|
|
|
|
extern int i2[__alignof(struct as6) == 2 ? 1 : -1];
|
|
|
|
|
|
|
|
union au6 {char c; __attribute__((packed, aligned(2))) int x;};
|
|
|
|
extern int k1[sizeof(union au6) == 4 ? 1 : -1];
|
|
|
|
extern int k2[__alignof(union au6) == 2 ? 1 : -1];
|
|
|
|
|
2008-10-04 01:33:35 +08:00
|
|
|
// Check postfix attributes
|
|
|
|
union au7 {char c; int x;} __attribute__((packed));
|
|
|
|
extern int l1[sizeof(union au7) == 4 ? 1 : -1];
|
|
|
|
extern int l2[__alignof(union au7) == 1 ? 1 : -1];
|
|
|
|
|
|
|
|
struct packed_fas2 {
|
|
|
|
char a;
|
|
|
|
int b[];
|
|
|
|
} __attribute__((packed));
|
|
|
|
|
|
|
|
extern int m1[sizeof(struct packed_fas2) == 1 ? 1 : -1];
|
|
|
|
extern int m2[__alignof(struct packed_fas2) == 1 ? 1 : -1];
|
2011-02-20 06:55:41 +08:00
|
|
|
|
|
|
|
// Attribute aligned can round down typedefs. PR9253
|
|
|
|
typedef long long __attribute__((aligned(1))) nt;
|
|
|
|
|
|
|
|
struct nS {
|
|
|
|
char buf_nr;
|
|
|
|
nt start_lba;
|
|
|
|
};
|
|
|
|
|
2014-08-05 06:48:19 +08:00
|
|
|
#if defined(_WIN32) && !defined(__declspec) // _MSC_VER is unavailable in cc1.
|
|
|
|
// Alignment doesn't affect packing in MS mode.
|
|
|
|
extern int n1[sizeof(struct nS) == 16 ? 1 : -1];
|
|
|
|
extern int n2[__alignof(struct nS) == 8 ? 1 : -1];
|
|
|
|
#else
|
2011-02-20 06:55:41 +08:00
|
|
|
extern int n1[sizeof(struct nS) == 9 ? 1 : -1];
|
|
|
|
extern int n2[__alignof(struct nS) == 1 ? 1 : -1];
|
2014-08-05 06:48:19 +08:00
|
|
|
#endif
|
2015-12-03 17:34:49 +08:00
|
|
|
|
|
|
|
// Packed attribute shouldn't be ignored for bit-field of char types.
|
|
|
|
// Note from GCC reference manual: The 4.1, 4.2 and 4.3 series of GCC ignore
|
|
|
|
// the packed attribute on bit-fields of type char. This has been fixed in
|
|
|
|
// GCC 4.4 but the change can lead to differences in the structure layout.
|
|
|
|
// See the documentation of -Wpacked-bitfield-compat for more information.
|
|
|
|
struct packed_chars {
|
|
|
|
char a:4;
|
|
|
|
char b:8 __attribute__ ((packed));
|
|
|
|
// expected-warning@-1 {{'packed' attribute was ignored on bit-fields with single-byte alignment in older versions of GCC and Clang}}
|
|
|
|
char c:4;
|
|
|
|
};
|
|
|
|
|
2015-12-04 00:03:34 +08:00
|
|
|
#if defined(_WIN32) && !defined(__declspec) // _MSC_VER is unavailable in cc1.
|
2015-12-03 17:34:49 +08:00
|
|
|
// On Windows clang uses MSVC compatible layout in this case.
|
|
|
|
extern int o1[sizeof(struct packed_chars) == 3 ? 1 : -1];
|
|
|
|
extern int o2[__alignof(struct packed_chars) == 1 ? 1 : -1];
|
|
|
|
#else
|
|
|
|
extern int o1[sizeof(struct packed_chars) == 2 ? 1 : -1];
|
|
|
|
extern int o2[__alignof(struct packed_chars) == 1 ? 1 : -1];
|
|
|
|
#endif
|