[committed] avoid assuming cfun is nonnull [PR102243]

Message ID 6b76d2ce-9ad8-bcc4-7bef-dd191b1a9b81@gmail.com
State Committed
Headers
Series [committed] avoid assuming cfun is nonnull [PR102243] |

Commit Message

Martin Sebor Sept. 19, 2021, 11:32 p.m. UTC
  After the front end passes control to the middle end cfun is never
null (I'm pretty sure) 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

    if (!rvals->range_of_expr (vr, val, stmt))
  

Comments

Richard Biener Sept. 20, 2021, 6:46 a.m. UTC | #1
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
>
  

Patch

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;