re PR c++/79681 (ICE with constexpr and bitfield)
authorJakub Jelinek <jakub@redhat.com>
Wed, 1 Mar 2017 09:02:12 +0000 (10:02 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Wed, 1 Mar 2017 09:02:12 +0000 (10:02 +0100)
PR c++/79681
* fold-const.c (make_bit_field_ref): If orig_inner is COMPONENT_REF,
attempt to use its first operand as BIT_FIELD_REF base.

* g++.dg/cpp1y/constexpr-79681-1.C: New test.
* g++.dg/cpp1y/constexpr-79681-2.C: New test.

From-SVN: r245804

gcc/ChangeLog
gcc/fold-const.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp1y/constexpr-79681-1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp1y/constexpr-79681-2.C [new file with mode: 0644]

index 253eab3456a3c154bccec58fafff81e3e5f6acbd..4873ae8eb9d6b982cd8d5c0bb52f78b300f2f333 100644 (file)
@@ -1,3 +1,9 @@
+2017-03-01  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c++/79681
+       * fold-const.c (make_bit_field_ref): If orig_inner is COMPONENT_REF,
+       attempt to use its first operand as BIT_FIELD_REF base.
+
 2017-03-01  Richard Biener  <rguenther@suse.de>
 
        PR middle-end/79721
index 3d63836068747f59338b8daa571f220013e44e0c..e64fa64232eb644f512dbcb698b1e6bd6ab17861 100644 (file)
@@ -3862,6 +3862,31 @@ make_bit_field_ref (location_t loc, tree inner, tree orig_inner, tree type,
 {
   tree result, bftype;
 
+  /* Attempt not to lose the access path if possible.  */
+  if (TREE_CODE (orig_inner) == COMPONENT_REF)
+    {
+      tree ninner = TREE_OPERAND (orig_inner, 0);
+      machine_mode nmode;
+      HOST_WIDE_INT nbitsize, nbitpos;
+      tree noffset;
+      int nunsignedp, nreversep, nvolatilep = 0;
+      tree base = get_inner_reference (ninner, &nbitsize, &nbitpos,
+                                      &noffset, &nmode, &nunsignedp,
+                                      &nreversep, &nvolatilep);
+      if (base == inner
+         && noffset == NULL_TREE
+         && nbitsize >= bitsize
+         && nbitpos <= bitpos
+         && bitpos + bitsize <= nbitpos + nbitsize
+         && !reversep
+         && !nreversep
+         && !nvolatilep)
+       {
+         inner = ninner;
+         bitpos -= nbitpos;
+       }
+    }
+
   alias_set_type iset = get_alias_set (orig_inner);
   if (iset == 0 && get_alias_set (inner) != iset)
     inner = fold_build2 (MEM_REF, TREE_TYPE (inner),
index 7aac384da2f8141d67776e4c44f1a0ac5375306e..5d7e177f2718c2425e8bfcaca00cab84d8b7009e 100644 (file)
@@ -5,6 +5,10 @@
 
 2017-03-01  Jakub Jelinek  <jakub@redhat.com>
 
+       PR c++/79681
+       * g++.dg/cpp1y/constexpr-79681-1.C: New test.
+       * g++.dg/cpp1y/constexpr-79681-2.C: New test.
+
        PR c++/79746
        * g++.dg/warn/Wunused-parm-9.C: New test.
 
diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-79681-1.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-79681-1.C
new file mode 100644 (file)
index 0000000..000afd8
--- /dev/null
@@ -0,0 +1,17 @@
+// PR c++/79681
+// { dg-do compile { target c++14 } }
+// { dg-options "-O2" }
+
+struct A
+{
+  int i : 4;
+};
+
+constexpr bool
+foo ()
+{
+  A x[] = { 1 };
+  return x[0].i;
+}
+
+static_assert (foo(), "");
diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-79681-2.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-79681-2.C
new file mode 100644 (file)
index 0000000..edca161
--- /dev/null
@@ -0,0 +1,39 @@
+// PR c++/79681
+// { dg-do compile { target c++14 } }
+// { dg-options "-O2" }
+
+struct A
+{
+  char i : 4;
+  char k : 1;
+  char l : 3;
+};
+struct B
+{
+  char j : 4;
+};
+struct C
+{
+  long long u;
+  A a[1];
+  B b[1];
+};
+
+constexpr bool
+foo ()
+{
+  C c = { 0, { { 5, 0, 2 } }, { { 6 } } };
+  C d = { 0, { { 6, 0, 1 } }, { { 5 } } };
+  return c.a[0].i == d.a[0].i && c.b[0].j == d.b[0].j;
+}
+
+constexpr bool
+bar ()
+{
+  C c = { 0, { { 5, 0, 2 } }, { { 6 } } };
+  C d = { 0, { { 6, 0, 1 } }, { { 5 } } };
+  return c.a[0].i == d.a[0].i && c.a[0].l == d.a[0].l;
+}
+
+static_assert (foo () == false, "");
+static_assert (bar () == false, "");