]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
openmp, c: Tighten up c_tree_equal [PR106981]
authorJakub Jelinek <jakub@redhat.com>
Sat, 24 Sep 2022 18:05:18 +0000 (20:05 +0200)
committerTobias Burnus <tobias@codesourcery.com>
Sat, 24 Sep 2022 18:05:18 +0000 (20:05 +0200)
This patch changes c_tree_equal to work more like cp_tree_equal, be
more strict in what it accepts.  The ICE on the first testcase was
due to INTEGER_CST wi::wide (t1) == wi::wide (t2) comparison which
ICEs if the two constants have different precision, but as the second
testcase shows, being too lenient in it can also lead to miscompilation
of valid OpenMP programs where we think certain expression is the same
even when it isn't and can be guaranteed at runtime to represent different
memory location.  So, the patch looks through only NON_LVALUE_EXPRs
and for constants as well as casts requires that the types match before
actually comparing the constant values or recursing on the cast operands.

2022-09-24  Jakub Jelinek  <jakub@redhat.com>

PR c/106981
gcc/c/
* c-typeck.cc (c_tree_equal): Only strip NON_LVALUE_EXPRs at the
start.  For CONSTANT_CLASS_P or CASE_CONVERT: return false if t1 and
t2 have different types.
gcc/testsuite/
* c-c++-common/gomp/pr106981.c: New test.
libgomp/
* testsuite/libgomp.c-c++-common/pr106981.c: New test.

(cherry picked from commit 3c5bccb608c665ac3f62adb1817c42c845812428)

gcc/c/ChangeLog.omp
gcc/c/c-typeck.cc
gcc/testsuite/ChangeLog.omp
gcc/testsuite/c-c++-common/gomp/pr106981.c [new file with mode: 0644]
libgomp/ChangeLog.omp
libgomp/testsuite/libgomp.c-c++-common/pr106981.c [new file with mode: 0644]

index 9d15f19b98d0802448d953e0decd36eaeb9b5518..e86fbc83a3141ee21f6422bb1f18bf349e2237c5 100644 (file)
@@ -1,3 +1,13 @@
+2022-09-24  Tobias Burnus  <tobias@codesourcery.com>
+
+       Backport from mainline:
+       2022-09-24  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c/106981
+       * c-typeck.cc (c_tree_equal): Only strip NON_LVALUE_EXPRs at the
+       start.  For CONSTANT_CLASS_P or CASE_CONVERT: return false if t1 and
+       t2 have different types.
+
 2022-09-06  Tobias Burnus  <tobias@codesourcery.com>
 
        Backport from mainline:
index a52aebd69afd350ca3538d1e14f0c9a4ee1c4b09..0dd3a444bb04d0c93b1268a7a7319ff6cbec0729 100644 (file)
@@ -16139,14 +16139,10 @@ c_tree_equal (tree t1, tree t2)
   if (!t1 || !t2)
     return false;
 
-  for (code1 = TREE_CODE (t1);
-       CONVERT_EXPR_CODE_P (code1)
-        || code1 == NON_LVALUE_EXPR;
+  for (code1 = TREE_CODE (t1); code1 == NON_LVALUE_EXPR;
        code1 = TREE_CODE (t1))
     t1 = TREE_OPERAND (t1, 0);
-  for (code2 = TREE_CODE (t2);
-       CONVERT_EXPR_CODE_P (code2)
-        || code2 == NON_LVALUE_EXPR;
+  for (code2 = TREE_CODE (t2); code2 == NON_LVALUE_EXPR;
        code2 = TREE_CODE (t2))
     t2 = TREE_OPERAND (t2, 0);
 
@@ -16157,6 +16153,9 @@ c_tree_equal (tree t1, tree t2)
   if (code1 != code2)
     return false;
 
+  if (CONSTANT_CLASS_P (t1) && !comptypes (TREE_TYPE (t1), TREE_TYPE (t2)))
+    return false;
+
   switch (code1)
     {
     case INTEGER_CST:
@@ -16276,6 +16275,11 @@ c_tree_equal (tree t1, tree t2)
        return true;
       }
 
+    CASE_CONVERT:
+      if (!comptypes (TREE_TYPE (t1), TREE_TYPE (t2)))
+       return false;
+      break;
+
     default:
       break;
     }
index 7b085e8254ebce05d60533cdb42635cd3e45b554..43968b7a28e357af8ecde510b11ac727426a25bb 100644 (file)
@@ -1,3 +1,11 @@
+2022-09-24  Tobias Burnus  <tobias@codesourcery.com>
+
+       Backport from mainline:
+       2022-09-24  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c/106981
+       * c-c++-common/gomp/pr106981.c: New test.
+
 2022-09-23  Tobias Burnus  <tobias@codesourcery.com>
 
        Backport from mainline:
diff --git a/gcc/testsuite/c-c++-common/gomp/pr106981.c b/gcc/testsuite/c-c++-common/gomp/pr106981.c
new file mode 100644 (file)
index 0000000..a21d3c2
--- /dev/null
@@ -0,0 +1,9 @@
+/* PR c/106981 */
+/* { dg-do compile } */
+
+void
+foo (int a, double *b, double *c, double *d, long long e)
+{
+#pragma omp atomic capture
+  c[a] = d[((int) (e / 10 + 1))] = b[a] + d[((int) e / 10 + 1)];       /* { dg-error "invalid form" } */
+}
index 20cc22d8434c8ffee1b7d7b1bbeb4116685f5c54..c01fa632080739340e8cb5806b7796c0a5968d46 100644 (file)
@@ -1,3 +1,11 @@
+2022-09-24  Tobias Burnus  <tobias@codesourcery.com>
+
+       Backport from mainline:
+       2022-09-24  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c/106981
+       * testsuite/libgomp.c-c++-common/pr106981.c: New test.
+
 2022-09-13  Tobias Burnus  <tobias@codesourcery.com>
 
        Backport from mainline:
diff --git a/libgomp/testsuite/libgomp.c-c++-common/pr106981.c b/libgomp/testsuite/libgomp.c-c++-common/pr106981.c
new file mode 100644 (file)
index 0000000..ed48d27
--- /dev/null
@@ -0,0 +1,19 @@
+/* PR c/106981 */
+
+int
+main ()
+{
+  int a[0x101];
+  unsigned int b = 0x100;
+  if ((unsigned char) b || (unsigned short) b != 0x100)
+    return 0;
+  a[0] = 0;
+  a[0x100] = 42;
+  #pragma omp atomic update
+  a[(unsigned char) b] = a[(unsigned short) b] + a[(unsigned char) b];
+  #pragma omp atomic update
+  a[(unsigned char) b] = a[(unsigned char) b] + a[(unsigned short) b];
+  if (a[0] != 84 || a[0x100] != 42)
+    __builtin_abort ();
+  return 0;
+}