On Mon, Sep 20, 2021 at 1:33 AM Martin Sebor via Gcc-patches <gcc-patches@gcc.gnu.org> wrote: > > After the front end passes control to the middle end cfun is never > null (I'm pretty sure)
cfun is NULL during IPA pass execution, it's set to non-NULL by the pass manager when we execute a non-IPA pass on a specific function only. Richard. > but when a middle end helper is called > from the C++ front end cfun can be null for a namespace scope > initializer expression. A recent change of mine to the helper > introduced an assumption to the contrary, causing an ICE. In > r12-3673 I've committed the trivial fix below to correct this > mistake > > Martin > > Handle null cfun [PR102243]. > > Resolves: > PR middle-end/102243 - ICE on placement new at global scope > > gcc/ChangeLog: > PR middle-end/102243 > * tree-ssa-strlen.c (get_range): Handle null cfun. > > gcc/testsuite/ChangeLog: > PR middle-end/102243 > * g++.dg/warn/Wplacement-new-size-10.C: New test. > --- > gcc/testsuite/g++.dg/warn/Wplacement-new-size-10.C | 13 +++++++++++++ > gcc/tree-ssa-strlen.c | 14 ++++++++++---- > 2 files changed, 23 insertions(+), 4 deletions(-) > create mode 100644 gcc/testsuite/g++.dg/warn/Wplacement-new-size-10.C > > diff --git a/gcc/testsuite/g++.dg/warn/Wplacement-new-size-10.C > b/gcc/testsuite/g++.dg/warn/Wplacement-new-size-10.C > new file mode 100644 > index 00000000000..6b71a832a30 > --- /dev/null > +++ b/gcc/testsuite/g++.dg/warn/Wplacement-new-size-10.C > @@ -0,0 +1,13 @@ > +/* PR middle-end/102243 - ICE on placement new at global scope > + { dg-do compile } > + { dg-options "-Wall" } */ > + > +void *operator new (__SIZE_TYPE__, void *); > + > +char a[2][sizeof (int)]; > + > +int *p = new (a[1]) int; > + > +void *operator new[] (__SIZE_TYPE__, void *p) { return p; } > + > +int *q = new (a[1]) int[1]; > diff --git a/gcc/tree-ssa-strlen.c b/gcc/tree-ssa-strlen.c > index 7c93958e9ad..7c568a42d49 100644 > --- a/gcc/tree-ssa-strlen.c > +++ b/gcc/tree-ssa-strlen.c > @@ -199,16 +199,22 @@ static bool handle_assign (gimple_stmt_iterator *, > tree, bool *, > > /* Sets MINMAX to either the constant value or the range VAL is in > and returns either the constant value or VAL on success or null > - when the range couldn't be determined. Uses RVALS when nonnull > - to determine the range, otherwise uses CFUN or global range info, > - whichever is nonnull. */ > + when the range couldn't be determined. Uses RVALS or CFUN for > + range info, whichever is nonnull. */ > > tree > get_range (tree val, gimple *stmt, wide_int minmax[2], > range_query *rvals /* = NULL */) > { > if (!rvals) > - rvals = get_range_query (cfun); > + { > + if (!cfun) > + /* When called from front ends for global initializers CFUN > + may be null. */ > + return NULL_TREE; > + > + rvals = get_range_query (cfun); > + } > > value_range vr; > if (!rvals->range_of_expr (vr, val, stmt)) > -- > 2.27.0 >