Handle undefined ranges in get_size_range.
authorAldy Hernandez <aldyh@redhat.com>
Fri, 23 Oct 2020 13:54:58 +0000 (15:54 +0200)
committerAldy Hernandez <aldyh@redhat.com>
Sat, 24 Oct 2020 08:38:33 +0000 (10:38 +0200)
An undefined range was leaking through to the end of this function,
which leads us to use an uninitialized wide_int.

gcc/ChangeLog:

PR tree-optimization/97538
* calls.c (get_size_range): Handle undefined ranges.

gcc/testsuite/ChangeLog:

* g++.dg/pr97538.C: New test.

gcc/calls.c
gcc/testsuite/g++.dg/pr97538.C [new file with mode: 0644]

index a12b847..17b8e2f 100644 (file)
@@ -1269,16 +1269,14 @@ get_size_range (range_query *query, tree exp, gimple *stmt, tree range[2],
       value_range vr;
       if (query && query->range_of_expr (vr, exp, stmt))
        {
+         if (vr.undefined_p ())
+           vr.set_varying (TREE_TYPE (exp));
          range_type = vr.kind ();
-         if (!vr.undefined_p ())
-           {
-             min = wi::to_wide (vr.min ());
-             max = wi::to_wide (vr.max ());
-           }
+         min = wi::to_wide (vr.min ());
+         max = wi::to_wide (vr.max ());
        }
       else
        range_type = determine_value_range (exp, &min, &max);
-
     }
   else
     range_type = VR_VARYING;
diff --git a/gcc/testsuite/g++.dg/pr97538.C b/gcc/testsuite/g++.dg/pr97538.C
new file mode 100644 (file)
index 0000000..b29b1e4
--- /dev/null
@@ -0,0 +1,27 @@
+// { dg-do compile }
+// { dg-options "-fno-guess-branch-probability -fno-tree-pta -O1" }
+
+void *b, *c;
+struct H {
+  virtual bool accept(const char *, unsigned long, int *, bool);
+};
+char accept_bt[1], accept_cd[1];
+int accept_cb;
+bool accept_cb_0;
+class t : H {
+  bool accept(const char *, unsigned long bd, int *bg, bool) {
+    long bu = sizeof(int) + bd;
+    char *bw = bu > sizeof(accept_bt) ? new char : accept_bt,
+         *cf = bd ? new char : accept_cd;
+    __builtin___memcpy_chk(b, c, bd, 0);
+    if (bw != accept_bt)
+      delete bw;
+    bool ci = cj((int *)cf, bg), atran = bp && accept_cb_0;
+    atran &&ci &&cm(&accept_cb);
+    return ci;
+  }
+  bool cj(int *, int *);
+  bool cm(int *);
+  bool bp;
+};
+void bj() { new t; }