From aca94d735e74a0cfbdbebfbc1c81aa03c0a3bdb3 Mon Sep 17 00:00:00 2001 From: Xavier Leroy Date: Tue, 12 Feb 2019 20:53:17 +0100 Subject: Add regression test for "aligned" attribute Expected results were obtained with GCC 5.4 and Clang 8.0 --- test/regression/Makefile | 2 +- test/regression/Results/aligned | 11 ++++ test/regression/aligned.c | 108 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 120 insertions(+), 1 deletion(-) create mode 100644 test/regression/Results/aligned create mode 100644 test/regression/aligned.c (limited to 'test/regression') diff --git a/test/regression/Makefile b/test/regression/Makefile index 5d40e2c9..760ee570 100644 --- a/test/regression/Makefile +++ b/test/regression/Makefile @@ -23,7 +23,7 @@ TESTS=int32 int64 floats floats-basics \ TESTS_COMP=attribs1 bitfields1 bitfields2 bitfields3 bitfields4 \ bitfields5 bitfields6 bitfields7 bitfields8 \ builtins-$(ARCH) packedstruct1 packedstruct2 alignas \ - varargs1 varargs2 varargs3 sections alias + varargs1 varargs2 varargs3 sections alias aligned # Can run, both in compiled mode and in interpreter mode, # but produce processor-dependent results, so no reference output in Results diff --git a/test/regression/Results/aligned b/test/regression/Results/aligned new file mode 100644 index 00000000..7a4f7c9f --- /dev/null +++ b/test/regression/Results/aligned @@ -0,0 +1,11 @@ +a: size 1, offset mod 16 = 0 +b: size 3, offset mod 16 = 0 +c: size is that of a pointer, offset mod 16 is good +d: size 1, offset mod 16 = 0 +f: size is that of a pointer, offset mod 16 is good +g: size 32, offset mod 16 = 0 +h: size 16, offset mod 16 = 0 +i: size 16, offset mod 16 = 0 +j: size 16, offset mod 16 = 0 +T2: size 112, alignment 16 +T4: size is that of a pointer, alignment is that of a pointer diff --git a/test/regression/aligned.c b/test/regression/aligned.c new file mode 100644 index 00000000..3b5a9374 --- /dev/null +++ b/test/regression/aligned.c @@ -0,0 +1,108 @@ +/* The "aligned" attribute */ + +#include + +#define ALIGNED __attribute((aligned(16))) + +typedef ALIGNED char c16; + +struct s { + char y; + char ALIGNED x; +}; + +typedef struct { char y; } ALIGNED u; + +struct { + char filler1; + + /* Base type */ + char ALIGNED a; + /* Array */ + /* Expected: array of 3 naturally-aligned chars -> size = 3 */ + ALIGNED char b[3]; + /* Pointer */ + /* Expected: 16-aligned pointer to naturally-aligned char */ + ALIGNED char * c; + +/* Typedef */ + + c16 d; + /* Expected: like char ALIGNED d */ + // c16 e[3] = {2, 3, 4}; + /* Expected: unclear. This one is rejected by gcc. + clang says size = 16, alignment = 16, but initializes first 3 bytes only. + compcert says size = 3, alignment = 16. */ + char filler2; + c16 * f; + /* Expected: naturally-aligned pointer to 16-aligned char */ + +/* Struct */ + + struct s g; + /* Expected: alignment 16, size 17 + (1 byte, padding to mod 16, 1 bytes) */ + + char filler3; + + struct t { + char y; + } ALIGNED h; + /* Expected: type struct t and variable h have alignment 16 and size 1 */ + + char filler4; + + struct t i; + /* Expected: alignment 16 and size 1. This checks that the ALIGNED + attribute is attached to "struct t". */ + + char filler5; + + u j; + /* Expected: type u and variable j have alignment 16 and size 1. */ +} x; + +typedef char T1[100]; + +typedef struct { T1 mess[1]; } ALIGNED T2; +/* Expected: alignment 16, size 112 = 100 aligned to 16 */ + +typedef T2 T3[]; + +typedef struct { T3 *area; } T4; +/* Expected: size of a pointer, alignment of a pointer */ + +void check(const char * msg, void * addr, size_t sz) +{ + printf("%s: size %zu, offset mod 16 = %lu\n", + msg, sz, (unsigned long) ((char *) addr - (char *) &x) % 16); +} + +void checkptr(const char * msg, void * addr, size_t sz, size_t al) +{ + printf("%s: size %s that of a pointer, offset mod 16 %s\n", + msg, + sz == sizeof(void *) ? "is" : "IS NOT", + (((char *) addr - (char *) &x) % 16) == al ? + "is good" : "IS BAD"); +} + +int main() +{ + check("a", &(x.a), sizeof(x.a)); + check("b", &(x.b), sizeof(x.b)); + checkptr("c", &(x.c), sizeof(x.c), 0); + check("d", &(x.d), sizeof(x.d)); + checkptr("f", &(x.f), sizeof(x.f), _Alignof(void *)); + check("g", &(x.g), sizeof(x.g)); + check("h", &(x.h), sizeof(x.h)); + check("i", &(x.i), sizeof(x.i)); + check("j", &(x.j), sizeof(x.j)); + + printf("T2: size %zu, alignment %zu\n", sizeof(T2), _Alignof(T2)); + printf("T4: size %s that of a pointer, alignment %s that of a pointer\n", + sizeof(T4) == sizeof(void *) ? "is" : "IS NOT", + _Alignof(T4) == _Alignof(void *) ? "is" : "IS NOT"); + + return 0; +} -- cgit