This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[patch 5/5] new -fstrict-volatile-bitfields test cases
- From: Sandra Loosemore <sandra at codesourcery dot com>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>, Richard Biener <richard dot guenther at gmail dot com>
- Date: Sun, 16 Jun 2013 13:09:10 -0600
- Subject: [patch 5/5] new -fstrict-volatile-bitfields test cases
Here are the test cases for the bugs fixed by this patch series. See my
original posting of this patch set
http://gcc.gnu.org/ml/gcc-patches/2013-06/msg00750.html
for discussion of which test cases were previously failing on what targets.
-Sandra
2013-06-16 Sandra Loosemore <sandra@codesourcery.com>
PR middle-end/23623
PR middle-end/48784
PR middle-end/56341
PR middle-end/56997
gcc/testsuite/
* gcc.dg/pr23623.c: New test.
* gcc.dg/pr48784-1.c: New test.
* gcc.dg/pr48784-2.c: New test.
* gcc.dg/pr56341-1.c: New test.
* gcc.dg/pr56341-2.c: New test.
* gcc.dg/pr56997-1.c: New test.
* gcc.dg/pr56997-2.c: New test.
* gcc.dg/pr56997-3.c: New test.
Index: gcc/testsuite/gcc.dg/pr23623.c
===================================================================
--- gcc/testsuite/gcc.dg/pr23623.c (revision 0)
+++ gcc/testsuite/gcc.dg/pr23623.c (revision 0)
@@ -0,0 +1,45 @@
+/* { dg-do compile } */
+/* { dg-options "-fstrict-volatile-bitfields -fdump-rtl-final" } */
+
+/* With -fstrict-volatile-bitfields, the volatile accesses to bf2.b
+ and bf3.b must do unsigned int reads/writes. The non-volatile
+ accesses to bf1.b are not so constrained. */
+
+extern struct
+{
+ unsigned int b : 1;
+} bf1;
+
+extern volatile struct
+{
+ unsigned int b : 1;
+} bf2;
+
+extern struct
+{
+ volatile unsigned int b : 1;
+} bf3;
+
+void writeb(void)
+{
+ bf1.b = 1;
+ bf2.b = 1; /* volatile read + volatile write */
+ bf3.b = 1; /* volatile read + volatile write */
+}
+
+extern unsigned int x1, x2, x3;
+
+void readb(void)
+{
+ x1 = bf1.b;
+ x2 = bf2.b; /* volatile write */
+ x3 = bf3.b; /* volatile write */
+}
+
+/* There should be 6 volatile MEMs total, but scan-rtl-dump-times counts
+ the number of match variables and not the number of matches. Since
+ the parenthesized subexpression in the regexp introduces an extra match
+ variable, we need to give a count of 12 instead of 6 here. */
+/* { dg-final { scan-rtl-dump-times "mem/v(/.)*:SI" 12 "final" } } */
+/* { dg-final { cleanup-rtl-dump "final" } } */
+
Index: gcc/testsuite/gcc.dg/pr48784-1.c
===================================================================
--- gcc/testsuite/gcc.dg/pr48784-1.c (revision 0)
+++ gcc/testsuite/gcc.dg/pr48784-1.c (revision 0)
@@ -0,0 +1,18 @@
+/* { dg-do run } */
+/* { dg-options "-fstrict-volatile-bitfields" } */
+
+#include <stdlib.h>
+
+#pragma pack(1)
+volatile struct S0 {
+ signed a : 7;
+ unsigned b : 28; /* b can't be fetched with an aligned 32-bit access, */
+ /* but it certainly can be fetched with an unaligned access */
+} g = {0,0xfffffff};
+
+int main() {
+ unsigned b = g.b;
+ if (b != 0xfffffff)
+ abort ();
+ return 0;
+}
Index: gcc/testsuite/gcc.dg/pr48784-2.c
===================================================================
--- gcc/testsuite/gcc.dg/pr48784-2.c (revision 0)
+++ gcc/testsuite/gcc.dg/pr48784-2.c (revision 0)
@@ -0,0 +1,18 @@
+/* { dg-do run } */
+/* { dg-options "-fno-strict-volatile-bitfields" } */
+
+#include <stdlib.h>
+
+#pragma pack(1)
+volatile struct S0 {
+ signed a : 7;
+ unsigned b : 28; /* b can't be fetched with an aligned 32-bit access, */
+ /* but it certainly can be fetched with an unaligned access */
+} g = {0,0xfffffff};
+
+int main() {
+ unsigned b = g.b;
+ if (b != 0xfffffff)
+ abort ();
+ return 0;
+}
Index: gcc/testsuite/gcc.dg/pr56341-1.c
===================================================================
--- gcc/testsuite/gcc.dg/pr56341-1.c (revision 0)
+++ gcc/testsuite/gcc.dg/pr56341-1.c (revision 0)
@@ -0,0 +1,41 @@
+/* { dg-do run } */
+/* { dg-options "-fstrict-volatile-bitfields" } */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+struct test0
+{
+ unsigned char b1[2];
+} __attribute__((packed, aligned(2)));
+
+struct test1
+{
+ volatile unsigned long a1;
+ unsigned char b1[4];
+} __attribute__((packed, aligned(2)));
+
+struct test2
+{
+ struct test0 t0;
+ struct test1 t1;
+ struct test0 t2;
+} __attribute__((packed, aligned(2)));
+
+struct test2 xx;
+struct test2 *x1 = &xx;
+
+#define MAGIC 0x12345678
+
+void test0 (struct test2* x1)
+{
+ x1->t1.a1 = MAGIC;
+}
+
+int main()
+{
+ test0 (x1);
+ if (xx.t1.a1 != MAGIC)
+ abort ();
+ return 0;
+}
Index: gcc/testsuite/gcc.dg/pr56341-2.c
===================================================================
--- gcc/testsuite/gcc.dg/pr56341-2.c (revision 0)
+++ gcc/testsuite/gcc.dg/pr56341-2.c (revision 0)
@@ -0,0 +1,41 @@
+/* { dg-do run } */
+/* { dg-options "-fno-strict-volatile-bitfields" } */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+struct test0
+{
+ unsigned char b1[2];
+} __attribute__((packed, aligned(2)));
+
+struct test1
+{
+ volatile unsigned long a1;
+ unsigned char b1[4];
+} __attribute__((packed, aligned(2)));
+
+struct test2
+{
+ struct test0 t0;
+ struct test1 t1;
+ struct test0 t2;
+} __attribute__((packed, aligned(2)));
+
+struct test2 xx;
+struct test2 *x1 = &xx;
+
+#define MAGIC 0x12345678
+
+void test0 (struct test2* x1)
+{
+ x1->t1.a1 = MAGIC;
+}
+
+int main()
+{
+ test0 (x1);
+ if (xx.t1.a1 != MAGIC)
+ abort ();
+ return 0;
+}
Index: gcc/testsuite/gcc.dg/pr56997-1.c
===================================================================
--- gcc/testsuite/gcc.dg/pr56997-1.c (revision 0)
+++ gcc/testsuite/gcc.dg/pr56997-1.c (revision 0)
@@ -0,0 +1,46 @@
+/* Test volatile access to unaligned field. */
+/* { dg-do run } */
+/* { dg-options "-fstrict-volatile-bitfields" } */
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdint.h>
+
+#define test_type uint16_t
+#define MAGIC 0x102u
+
+typedef struct s{
+ unsigned char Prefix;
+ test_type Type;
+}__attribute((__packed__)) ss;
+
+volatile ss v;
+ss g;
+
+void __attribute__((noinline))
+foo (test_type u)
+{
+ v.Type = u;
+}
+
+test_type __attribute__((noinline))
+bar (void)
+{
+ return v.Type;
+}
+
+int main()
+{
+ test_type temp;
+ foo(MAGIC);
+ memcpy(&g, (void *)&v, sizeof(g));
+ if (g.Type != MAGIC)
+ abort ();
+
+ g.Type = MAGIC;
+ memcpy((void *)&v, &g, sizeof(v));
+ temp = bar();
+ if (temp != MAGIC)
+ abort ();
+ return 0;
+}
Index: gcc/testsuite/gcc.dg/pr56997-2.c
===================================================================
--- gcc/testsuite/gcc.dg/pr56997-2.c (revision 0)
+++ gcc/testsuite/gcc.dg/pr56997-2.c (revision 0)
@@ -0,0 +1,46 @@
+/* Test volatile access to unaligned field. */
+/* { dg-do run } */
+/* { dg-options "-fstrict-volatile-bitfields" } */
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdint.h>
+
+#define test_type uint32_t
+#define MAGIC 0x1020304u
+
+typedef struct s{
+ unsigned char Prefix;
+ test_type Type;
+}__attribute((__packed__)) ss;
+
+volatile ss v;
+ss g;
+
+void __attribute__((noinline))
+foo (test_type u)
+{
+ v.Type = u;
+}
+
+test_type __attribute__((noinline))
+bar (void)
+{
+ return v.Type;
+}
+
+int main()
+{
+ test_type temp;
+ foo(MAGIC);
+ memcpy(&g, (void *)&v, sizeof(g));
+ if (g.Type != MAGIC)
+ abort ();
+
+ g.Type = MAGIC;
+ memcpy((void *)&v, &g, sizeof(v));
+ temp = bar();
+ if (temp != MAGIC)
+ abort ();
+ return 0;
+}
Index: gcc/testsuite/gcc.dg/pr56997-3.c
===================================================================
--- gcc/testsuite/gcc.dg/pr56997-3.c (revision 0)
+++ gcc/testsuite/gcc.dg/pr56997-3.c (revision 0)
@@ -0,0 +1,46 @@
+/* Test volatile access to unaligned field. */
+/* { dg-do run } */
+/* { dg-options "-fstrict-volatile-bitfields" } */
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdint.h>
+
+#define test_type uint64_t
+#define MAGIC 0x102030405060708ul
+
+typedef struct s{
+ unsigned char Prefix;
+ test_type Type;
+}__attribute((__packed__)) ss;
+
+volatile ss v;
+ss g;
+
+void __attribute__((noinline))
+foo (test_type u)
+{
+ v.Type = u;
+}
+
+test_type __attribute__((noinline))
+bar (void)
+{
+ return v.Type;
+}
+
+int main()
+{
+ test_type temp;
+ foo(MAGIC);
+ memcpy(&g, (void *)&v, sizeof(g));
+ if (g.Type != MAGIC)
+ abort ();
+
+ g.Type = MAGIC;
+ memcpy((void *)&v, &g, sizeof(v));
+ temp = bar();
+ if (temp != MAGIC)
+ abort ();
+ return 0;
+}