aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorAldy Hernandez <aldyh@redhat.com>2020-10-23 15:54:58 +0200
committerAldy Hernandez <aldyh@redhat.com>2020-10-24 10:38:33 +0200
commit16e2427f50c208dfe07d07f18009969502c25dc8 (patch)
tree73a81d852f46e6b10b293b30a1029dbefffde12a /gcc
parenta29ff9c53a77b6e208350d8c6db0f3e988f61d1f (diff)
downloadgcc-16e2427f50c208dfe07d07f18009969502c25dc8.zip
gcc-16e2427f50c208dfe07d07f18009969502c25dc8.tar.gz
gcc-16e2427f50c208dfe07d07f18009969502c25dc8.tar.bz2
Handle undefined ranges in get_size_range.
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.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/calls.c10
-rw-r--r--gcc/testsuite/g++.dg/pr97538.C27
2 files changed, 31 insertions, 6 deletions
diff --git a/gcc/calls.c b/gcc/calls.c
index a12b847..17b8e2f 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -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
index 0000000..b29b1e4
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pr97538.C
@@ -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; }