On Fri, Feb 18, 2022 at 10:40 PM apinski--- via Gcc-patches
wrote:
>
> From: Andrew Pinski
>
> The problem here is we end up with an error_mark_node when calling
> useless_type_conversion_p and that ICEs. STRIP_NOPS/tree_nop_conversion
> has had a check for the inner type being an error_mark_node since
> g9a6bb3f78c96
> (2000). This just adds the check also to tree_ssa_useless_type_conversion.
> STRIP_USELESS_TYPE_CONVERSION is mostly used inside the gimplifier
> and the places where it is used outside of the gimplifier would not
> be adding too much overhead.
>
> OK? Bootstrapped and tested on x86_64-linux-gnu with no regressions.
OK.
> Thanks,
> Andrew Pinski
>
> PR c/104506
>
> gcc/ChangeLog:
>
> * tree-ssa.cc (tree_ssa_useless_type_conversion):
> Check the inner type before calling useless_type_conversion_p.
>
> gcc/testsuite/ChangeLog:
>
> * gcc.dg/pr104506-1.c: New test.
> * gcc.dg/pr104506-2.c: New test.
> * gcc.dg/pr104506-3.c: New test.
> ---
> gcc/testsuite/gcc.dg/pr104506-1.c | 12
> gcc/testsuite/gcc.dg/pr104506-2.c | 11 +++
> gcc/testsuite/gcc.dg/pr104506-3.c | 11 +++
> gcc/tree-ssa.cc | 20 +---
> 4 files changed, 47 insertions(+), 7 deletions(-)
> create mode 100644 gcc/testsuite/gcc.dg/pr104506-1.c
> create mode 100644 gcc/testsuite/gcc.dg/pr104506-2.c
> create mode 100644 gcc/testsuite/gcc.dg/pr104506-3.c
>
> diff --git a/gcc/testsuite/gcc.dg/pr104506-1.c
> b/gcc/testsuite/gcc.dg/pr104506-1.c
> new file mode 100644
> index 000..5eb71911b71
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/pr104506-1.c
> @@ -0,0 +1,12 @@
> +/* { dg-do compile } */
> +/* { dg-options "-std=gnu11" } */
> +/* PR c/104506: we used to ICE after the error of
> + changing the type. */
> +
> +void
> +foo (double x)
> +/* { dg-message "note: previous definition" "previous definition" { target
> *-*-* } .-1 } */
> +{
> + (void)x;
> + int x; /* { dg-error "redeclared as different kind of symbol" } */
> +}
> diff --git a/gcc/testsuite/gcc.dg/pr104506-2.c
> b/gcc/testsuite/gcc.dg/pr104506-2.c
> new file mode 100644
> index 000..3c3c4f8
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/pr104506-2.c
> @@ -0,0 +1,11 @@
> +/* { dg-do compile } */
> +/* { dg-options "-std=gnu11" } */
> +/* PR c/104506: we used to ICE after the error of
> + changing the type. */
> +void
> +foo (double x)
> +/* { dg-message "note: previous definition" "previous definition" { target
> *-*-* } .-1 } */
> +{
> + x;
> + int x; /* { dg-error "redeclared as different kind of symbol" } */
> +}
> diff --git a/gcc/testsuite/gcc.dg/pr104506-3.c
> b/gcc/testsuite/gcc.dg/pr104506-3.c
> new file mode 100644
> index 000..b14deb5cf25
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/pr104506-3.c
> @@ -0,0 +1,11 @@
> +/* { dg-do compile } */
> +/* PR c/104506: we used to ICE after the error of
> + changing the type. */
> +double x;
> +/* { dg-message "note: previous declaration" "previous declaration" { target
> *-*-* } .-1 } */
> +void
> +foo (void)
> +{
> + x;
> +}
> +int x; /* { dg-error "conflicting types" } */
> diff --git a/gcc/tree-ssa.cc b/gcc/tree-ssa.cc
> index 430875ae37a..423dd871d9e 100644
> --- a/gcc/tree-ssa.cc
> +++ b/gcc/tree-ssa.cc
> @@ -1256,18 +1256,24 @@ delete_tree_ssa (struct function *fn)
> bool
> tree_ssa_useless_type_conversion (tree expr)
> {
> + tree outer_type, inner_type;
> +
>/* If we have an assignment that merely uses a NOP_EXPR to change
> the top of the RHS to the type of the LHS and the type conversion
> is "safe", then strip away the type conversion so that we can
> enter LHS = RHS into the const_and_copies table. */
> - if (CONVERT_EXPR_P (expr)
> - || TREE_CODE (expr) == VIEW_CONVERT_EXPR
> - || TREE_CODE (expr) == NON_LVALUE_EXPR)
> -return useless_type_conversion_p
> - (TREE_TYPE (expr),
> - TREE_TYPE (TREE_OPERAND (expr, 0)));
> + if (!CONVERT_EXPR_P (expr)
> + && TREE_CODE (expr) != VIEW_CONVERT_EXPR
> + && TREE_CODE (expr) != NON_LVALUE_EXPR)
> +return false;
>
> - return false;
> + outer_type = TREE_TYPE (expr);
> + inner_type = TREE_TYPE (TREE_OPERAND (expr, 0));
> +
> + if (inner_type == error_mark_node)
> +return false;
> +
> + return useless_type_conversion_p (outer_type, inner_type);
> }
>
> /* Strip conversions from EXP according to
> --
> 2.17.1
>