aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorXavier Leroy <xavier.leroy@college-de-france.fr>2019-02-12 20:53:17 +0100
committerXavier Leroy <xavierleroy@users.noreply.github.com>2019-02-25 17:15:36 +0100
commitaca94d735e74a0cfbdbebfbc1c81aa03c0a3bdb3 (patch)
tree6ef85c4164be3f5fd68c2e1aada61a67fdba4d55
parentd7dfc21c20f55b705e3e749c2c7b31f9a4611c39 (diff)
downloadcompcert-aca94d735e74a0cfbdbebfbc1c81aa03c0a3bdb3.tar.gz
compcert-aca94d735e74a0cfbdbebfbc1c81aa03c0a3bdb3.zip
Add regression test for "aligned" attribute
Expected results were obtained with GCC 5.4 and Clang 8.0
-rw-r--r--test/regression/Makefile2
-rw-r--r--test/regression/Results/aligned11
-rw-r--r--test/regression/aligned.c108
3 files changed, 120 insertions, 1 deletions
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 <stdio.h>
+
+#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;
+}