aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexandre Oliva <oliva@adacore.com>2025-01-10 09:32:43 -0300
committerAlexandre Oliva <oliva@gnu.org>2025-01-10 09:40:39 -0300
commitfd4e979d0c66567c2cb89f97b51abd35a8773d88 (patch)
treeef53c252da10edb63f21b42478171e53e7451e0b
parent740c84975ceb7426da656dc7115445872a9e5b6f (diff)
downloadgcc-fd4e979d0c66567c2cb89f97b51abd35a8773d88.zip
gcc-fd4e979d0c66567c2cb89f97b51abd35a8773d88.tar.gz
gcc-fd4e979d0c66567c2cb89f97b51abd35a8773d88.tar.bz2
[ifcombine] fix mask variable test to match use [PR118344]
There was a cut&pasto in the rr_and_mask's adjustment to match the combined type: the test on whether there was a mask already was testing the wrong variable, and then it might crash or otherwise fail accessing an undefined mask. This only hit with checking enabled, and rarely at that. for gcc/ChangeLog PR tree-optimization/118344 * gimple-fold.cc (fold_truth_andor_for_ifcombine): Fix typo in rr_and_mask's type adjustment test. for gcc/testsuite/ChangeLog PR tree-optimization/118344 * gcc.dg/field-merge-19.c: New.
-rw-r--r--gcc/gimple-fold.cc2
-rw-r--r--gcc/testsuite/gcc.dg/field-merge-19.c41
2 files changed, 42 insertions, 1 deletions
diff --git a/gcc/gimple-fold.cc b/gcc/gimple-fold.cc
index 0ad92de..20b5024 100644
--- a/gcc/gimple-fold.cc
+++ b/gcc/gimple-fold.cc
@@ -8644,7 +8644,7 @@ fold_truth_andor_for_ifcombine (enum tree_code code, tree truth_type,
xlr_bitpos);
else
lr_mask = wi::shifted_mask (xlr_bitpos, lr_bitsize, false, rnprec);
- if (rl_and_mask.get_precision ())
+ if (rr_and_mask.get_precision ())
rr_mask = wi::lshift (wide_int::from (rr_and_mask, rnprec, UNSIGNED),
xrr_bitpos);
else
diff --git a/gcc/testsuite/gcc.dg/field-merge-19.c b/gcc/testsuite/gcc.dg/field-merge-19.c
new file mode 100644
index 0000000..5622baa
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/field-merge-19.c
@@ -0,0 +1,41 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fchecking" } */
+
+/* PR tree-optimization/118344 */
+
+/* This used to ICE attempting to extend a mask variable after testing the
+ wrong mask variable. */
+
+int d, e, g, h, i, c, j;
+static short k;
+char o;
+static int *p;
+static long *a;
+int b[0];
+int q(int s, int t, int *u, int *v) {
+ for (int f = 0; f < s; f++)
+ if ((t & v[f]) != u[f])
+ return 0;
+ return 1;
+}
+int w(int s, int t) {
+ int l[] = {t, t, t, t}, m[] = {e, e, 3, 1};
+ int n = q(s, d, l, m);
+ return n;
+}
+int x(unsigned s) {
+ unsigned r;
+ if (s >= -1)
+ return 1;
+ r = 10000000;
+ while (s > 1 / r)
+ r /= 2;
+ return g ? 2 : 0;
+}
+void y() {
+ for (;;) {
+ b[w(8, *p)] = h;
+ for (; a + k; j = o)
+ i &= c = x(6) < 0;
+ }
+}