PR tree-optimization/94131 - ICE on printf with a VLA string and -fno-tree-ccp
authorMartin Sebor <msebor@redhat.com>
Wed, 25 Mar 2020 15:39:50 +0000 (09:39 -0600)
committerJeff Law <law@redhat.com>
Wed, 25 Mar 2020 15:39:50 +0000 (09:39 -0600)
gcc/testsuite/ChangeLog:

PR tree-optimization/94131
* gcc.dg/pr94131.c: New test.

gcc/ChangeLog:

PR tree-optimization/94131
* gimple-fold.c (get_range_strlen_tree): Fail for variable-length
types and decls.
* tree-ssa-strlen.c (get_range_strlen_dynamic): Avoid assuming
types have constant sizes.

gcc/ChangeLog
gcc/gimple-fold.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr84131.c [new file with mode: 0644]
gcc/tree-ssa-strlen.c

index baf0ab727f31d3aa171e69417bea1f5d8cc76d7f..b75ac74e73a37b380cd85701c22a6ce4084b0e39 100644 (file)
@@ -1,3 +1,11 @@
+2020-03-25  Martin Sebor  <msebor@redhat.com>
+
+       PR tree-optimization/94131
+       * gimple-fold.c (get_range_strlen_tree): Fail for variable-length
+       types and decls.
+       * tree-ssa-strlen.c (get_range_strlen_dynamic): Avoid assuming
+       types have constant sizes.
+
 2020-03-25  Martin Liska  <mliska@suse.cz>
 
        PR lto/94259
index c5939f19f59a3b823622e2fd222134a243b3ffc4..55b78fa284f101df3f5e9a1b59e887f5a5fdc323 100644 (file)
@@ -1378,7 +1378,9 @@ get_range_strlen_tree (tree arg, bitmap *visited, strlen_range_kind rkind,
 
          /* Fail when the array bound is unknown or zero.  */
          val = TYPE_SIZE_UNIT (optype);
-         if (!val || integer_zerop (val))
+         if (!val
+             || TREE_CODE (val) != INTEGER_CST
+             || integer_zerop (val))
            return false;
 
          val = fold_build2 (MINUS_EXPR, TREE_TYPE (val), val,
@@ -1412,7 +1414,9 @@ get_range_strlen_tree (tree arg, bitmap *visited, strlen_range_kind rkind,
 
          /* Fail when the array bound is unknown or zero.  */
          val = TYPE_SIZE_UNIT (optype);
-         if (!val || integer_zerop (val))
+         if (!val
+             || TREE_CODE (val) != INTEGER_CST
+             || integer_zerop (val))
            return false;
          val = fold_build2 (MINUS_EXPR, TREE_TYPE (val), val,
                             integer_one_node);
@@ -1448,7 +1452,9 @@ get_range_strlen_tree (tree arg, bitmap *visited, strlen_range_kind rkind,
              /* Fail if the offset is out of bounds.  Such accesses
                 should be diagnosed at some point.  */
              val = DECL_SIZE_UNIT (ref);
-             if (!val || integer_zerop (val))
+             if (!val
+                 || TREE_CODE (val) != INTEGER_CST
+                 || integer_zerop (val))
                return false;
 
              poly_offset_int psiz = wi::to_offset (val);
index 5fa61f94349a58b165c2f37a9ca263aa6cec7ec2..7f2d590871378050ca97a3e33f198657a472e5dc 100644 (file)
@@ -1,3 +1,8 @@
+2020-03-25  Martin Sebor  <msebor@redhat.com>
+
+       PR tree-optimization/94131
+       * gcc.dg/pr94131.c: New test.
+
 2020-03-25  Sandra Loosemore  <sandra@codesourcery.com>
 
        * gcc.dg/pr92301.c (main): Allow argc to be 0 to support
diff --git a/gcc/testsuite/gcc.dg/pr84131.c b/gcc/testsuite/gcc.dg/pr84131.c
new file mode 100644 (file)
index 0000000..0ba9651
--- /dev/null
@@ -0,0 +1,29 @@
+/* PR 94131 - ICE on printf with a VLA string and -fno-tree-ccp
+   -fno-tree-forwprop
+   { dg-do compile }
+   { dg-options "-O1 -fno-tree-ccp -fno-tree-forwprop" } */
+
+void rv1 (int n)
+{
+  char a[n];
+  __INTPTR_TYPE__ i = (__INTPTR_TYPE__ )&a[0];
+  i &= 3;
+
+  __builtin_memset (a, '\0', sizeof a);
+  __builtin_printf ("%s", i ? &a[0] : "");
+}
+
+
+void sink (void*);
+
+void rv2 (int n)
+{
+  char a[n];
+  __INTPTR_TYPE__ i = (__INTPTR_TYPE__)&a[0];
+  i &= 3;
+
+  __builtin_memset (a, '\0', sizeof a);
+  __builtin_printf ("%s", i ? &a[0] : "");
+
+  sink (a);
+}
index 6dd37fb0b785b6b1616ef04cf771de58a4b6dc23..93d095e18961e9c7f377a3e95ddbf0e66dea50a5 100644 (file)
@@ -1140,10 +1140,16 @@ get_range_strlen_dynamic (tree src, c_strlen_data *pdata, bitmap *visited,
            {
              tree basetype = TREE_TYPE (base);
              tree size = TYPE_SIZE_UNIT (basetype);
-             ++off;   /* Increment for the terminating nul.  */
-             pdata->maxlen = fold_build2 (MINUS_EXPR, size_type_node, size,
-                                          build_int_cst (size_type_node, off));
-             pdata->maxbound = pdata->maxlen;
+             if (TREE_CODE (size) == INTEGER_CST)
+               {
+                 ++off;   /* Increment for the terminating nul.  */
+                 tree toffset = build_int_cst (size_type_node, off);
+                 pdata->maxlen = fold_build2 (MINUS_EXPR, size_type_node, size,
+                                              toffset);
+                 pdata->maxbound = pdata->maxlen;
+               }
+             else      
+               pdata->maxlen = build_all_ones_cst (size_type_node);
            }
          else
            pdata->maxlen = build_all_ones_cst (size_type_node);