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.
This commit is contained in:
Aldy Hernandez 2020-10-23 15:54:58 +02:00
parent a29ff9c53a
commit 16e2427f50
2 changed files with 31 additions and 6 deletions

View 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;

View File

@ -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; }