]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
PR tree-optimization/92157 - incorrect strcmp() == 0 result for unknown strings
authormsebor <msebor@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 18 Oct 2019 22:26:39 +0000 (22:26 +0000)
committermsebor <msebor@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 18 Oct 2019 22:26:39 +0000 (22:26 +0000)
gcc/testsuite/ChangeLog:

PR tree-optimization/92157
* gcc.dg/strlenopt-69.c: Disable test failing due to PR 92155.
* gcc.dg/strlenopt-87.c: New test.

gcc/ChangeLog:

PR tree-optimization/92157
* tree-ssa-strlen.c (handle_builtin_string_cmp): Be prepared for
compute_string_length to return a negative result.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@277194 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/strlenopt-69.c
gcc/testsuite/gcc.dg/strlenopt-87.c [new file with mode: 0644]
gcc/tree-ssa-strlen.c

index 6ef72d484a4d692c620caf45b59ec3cd5fe82cb4..ccf870c2531f8ea6933747f24531cdd7b73b9e5f 100644 (file)
@@ -1,3 +1,9 @@
+2019-10-18  Martin Sebor  <msebor@redhat.com>
+
+       PR tree-optimization/92157
+       * tree-ssa-strlen.c (handle_builtin_string_cmp): Be prepared for
+       compute_string_length to return a negative result.
+
 2019-10-18  Richard Earnshaw  <rearnsha@arm.com>
 
        * config/arm/arm.md (negv<SIDI:mode>3): New expansion rule.
index 58757027b9c6314839676a686dd883656116a21b..1a87247323e94a572197902cbeeed7685e20290a 100644 (file)
@@ -1,3 +1,9 @@
+2019-10-18  Martin Sebor  <msebor@redhat.com>
+
+       PR tree-optimization/92157
+       * gcc.dg/strlenopt-69.c: Disable test failing due to PR 92155.
+       * gcc.dg/strlenopt-87.c: New test.
+
 2019-10-18  Richard Earnshaw  <rearnsha@arm.com>
 
        * gcc.target/arm/negdi-3.c: Update expected output to allow NEGS.
index 46ceb9ddb054dc5f891cc64afc0e34ff9c37a4b1..9ad8e2e8aacad033bf000a1292da6b2eae1c1b76 100644 (file)
@@ -66,11 +66,14 @@ void test_empty_string (void)
   b4[2] = '\0';
   A (0 == strcmp (&a4[2], &b4[2]));
 
+#if 0
+  /* The following isn't handled yet due to PR 92155.  */
   clobber (a4, b4);
 
   memset (a4, 0, sizeof a4);
   memset (b4, 0, sizeof b4);
   A (0 == strcmp (a4, b4));
+#endif
 }
 
 /* Verify that comparison of dynamically created strings with unknown
diff --git a/gcc/testsuite/gcc.dg/strlenopt-87.c b/gcc/testsuite/gcc.dg/strlenopt-87.c
new file mode 100644 (file)
index 0000000..082c7b2
--- /dev/null
@@ -0,0 +1,105 @@
+/* PR tree-optimization/92157 - incorrect strcmp() == 0 result for unknown
+   strings​
+   { dg-do run }
+   { dg-options "-O2 -Wall" } */
+
+#include "strlenopt.h"
+
+
+char a2[2], a3[3];
+
+
+static inline __attribute__ ((always_inline)) int
+verify_not_equal (const char *s, const char *t, int x)
+{
+  int n = x < 0 ? strlen (s) : 0 < x ? strlen (t) : strlen (s) + strlen (t);
+
+  if (strcmp (t, s) == 0)
+    abort ();
+
+  return n;
+}
+
+__attribute__ ((noipa)) int test_a2_s (const char *s)
+{
+  return verify_not_equal (a2, s, 0);
+}
+
+__attribute__ ((noipa)) int test_a2_a3 (void)
+{
+  return verify_not_equal (a2, a3, 0);
+}
+
+__attribute__ ((noipa)) int test_a3_a2 (void)
+{
+  return verify_not_equal (a3, a2, 0);
+}
+
+__attribute__ ((noipa)) int test_s_a2 (const char *s)
+{
+  return verify_not_equal (s, a2, 0);
+}
+
+
+__attribute__ ((noipa)) int test_a2_s_1 (const char *s)
+{
+  return verify_not_equal (a2, s, -1);
+}
+
+__attribute__ ((noipa)) int test_a2_a3_1 (void)
+{
+  return verify_not_equal (a2, a3, -1);
+}
+
+__attribute__ ((noipa)) int test_a3_a2_1 (void)
+{
+  return verify_not_equal (a3, a2, -1);
+}
+
+__attribute__ ((noipa)) int test_s_a2_1 (const char *s)
+{
+  return verify_not_equal (s, a2, -1);
+}
+
+
+__attribute__ ((noipa)) int test_a2_s_2 (const char *s)
+{
+  return verify_not_equal (a2, s, +1);
+}
+
+__attribute__ ((noipa)) int test_a2_a3_2 (void)
+{
+  return verify_not_equal (a2, a3, +1);
+}
+
+__attribute__ ((noipa)) int test_a3_a2_2 (void)
+{
+  return verify_not_equal (a3, a2, +1);
+}
+
+__attribute__ ((noipa)) int test_s_a2_2 (const char *s)
+{
+  return verify_not_equal (s, a2, +1);
+}
+
+int main (void)
+{
+  a2[0] = '1';
+  a3[0] = '1';
+  a3[0] = '2';
+
+  test_a2_s ("");
+  test_a2_a3 ();
+  test_a3_a2 ();
+  test_s_a2 ("");
+
+  test_a2_s_1 ("");
+  test_a2_a3_1 ();
+  test_a3_a2_1 ();
+  test_s_a2_1 ("");
+
+  test_a2_s_2 ("");
+  test_a2_a3_2 ();
+  test_a3_a2_2 ();
+  test_s_a2_2 ("");
+}
index d5833f69766f71cf8eac981d2490b6842ba1de10..43814584a147d8f1236ae541800144393e8097be 100644 (file)
@@ -3842,7 +3842,7 @@ handle_builtin_string_cmp (gimple_stmt_iterator *gsi)
   HOST_WIDE_INT arysiz1 = -1, arysiz2 = -1;
 
   if (idx1)
-    cstlen1 = compute_string_length (idx1) + 1;
+    cstlen1 = compute_string_length (idx1);
   else
     arysiz1 = determine_min_objsize (arg1);
 
@@ -3853,13 +3853,21 @@ handle_builtin_string_cmp (gimple_stmt_iterator *gsi)
 
   /* Repeat for the second argument.  */
   if (idx2)
-    cstlen2 = compute_string_length (idx2) + 1;
+    cstlen2 = compute_string_length (idx2);
   else
     arysiz2 = determine_min_objsize (arg2);
 
   if (cstlen2 < 0 && arysiz2 < 0)
     return false;
 
+  if (cstlen1 < 0 && cstlen2 < 0)
+    return false;
+
+  if (cstlen1 >= 0)
+    ++cstlen1;
+  if (cstlen2 >= 0)
+    ++cstlen2;
+
   /* The exact number of characters to compare.  */
   HOST_WIDE_INT cmpsiz = bound < 0 ? cstlen1 < 0 ? cstlen2 : cstlen1 : bound;
   /* The size of the array in which the unknown string is stored.  */