Re: [PATCH] Fix expansion ICE on store to CONST_DECL (PR middle-end/77959)

2016-10-14 Thread Richard Biener
On October 14, 2016 7:20:43 PM GMT+02:00, Jakub Jelinek  
wrote:
>Hi!
>
>The following (invalid) testcase ICEs, because we try to store into
>CONST_DECL's FIELD.  Normally in GIMPLE we have MEM_REF[] and
>writes to that expand gracefully into a MEM, but as soon as we use
>get_inner_reference in expand_assignment (even if the MEM is just
>reverse
>order, or we just want to store to a part of it etc.),
>get_inner_reference
>looks through even that MEM_REF.  Instead of hacking that around in
>expand_assignment, just attempting to handle EXPAND_WRITE into
>CONST_DECL
>looked easier to me.
>
>Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

OK.

Richard.

>2016-10-14  Jakub Jelinek  
>
>   PR middle-end/77959
>   * expr.c (expand_expr_real_1) : For EXPAND_WRITE
>   return a MEM.
>
>   * gfortran.dg/pr77959.f90: New test.
>
>--- gcc/expr.c.jj  2016-10-09 13:19:09.0 +0200
>+++ gcc/expr.c 2016-10-13 11:49:36.386993921 +0200
>@@ -9914,6 +9914,19 @@ expand_expr_real_1 (tree exp, rtx target
>   }
> 
> case CONST_DECL:
>+  if (modifier == EXPAND_WRITE)
>+  {
>+/* Writing into CONST_DECL is always invalid, but handle it
>+   gracefully.  */
>+addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (exp));
>+machine_mode address_mode = targetm.addr_space.address_mode (as);
>+op0 = expand_expr_addr_expr_1 (exp, NULL_RTX, address_mode,
>+   EXPAND_NORMAL, as);
>+op0 = memory_address_addr_space (mode, op0, as);
>+temp = gen_rtx_MEM (mode, op0);
>+set_mem_addr_space (temp, as);
>+return temp;
>+  }
>   return expand_expr (DECL_INITIAL (exp), target, VOIDmode, modifier);
> 
> case REAL_CST:
>--- gcc/testsuite/gfortran.dg/pr77959.f90.jj   2016-10-13
>11:57:30.019992471 +0200
>+++ gcc/testsuite/gfortran.dg/pr77959.f90  2016-10-13 11:58:50.719969914
>+0200
>@@ -0,0 +1,16 @@
>+! PR middle-end/77959
>+! { dg-do compile }
>+! { dg-options "-O2" }
>+
>+program pr77959
>+  interface
>+subroutine foo(x)  ! { dg-warning "Type mismatch in argument" }
>+  real :: x
>+end
>+  end interface
>+  call foo(1.0)
>+end
>+subroutine foo(x)
>+  complex :: x
>+  x = x + 1
>+end
>
>   Jakub




[PATCH] Fix expansion ICE on store to CONST_DECL (PR middle-end/77959)

2016-10-14 Thread Jakub Jelinek
Hi!

The following (invalid) testcase ICEs, because we try to store into
CONST_DECL's FIELD.  Normally in GIMPLE we have MEM_REF[] and
writes to that expand gracefully into a MEM, but as soon as we use
get_inner_reference in expand_assignment (even if the MEM is just reverse
order, or we just want to store to a part of it etc.), get_inner_reference
looks through even that MEM_REF.  Instead of hacking that around in
expand_assignment, just attempting to handle EXPAND_WRITE into CONST_DECL
looked easier to me.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2016-10-14  Jakub Jelinek  

PR middle-end/77959
* expr.c (expand_expr_real_1) : For EXPAND_WRITE
return a MEM.

* gfortran.dg/pr77959.f90: New test.

--- gcc/expr.c.jj   2016-10-09 13:19:09.0 +0200
+++ gcc/expr.c  2016-10-13 11:49:36.386993921 +0200
@@ -9914,6 +9914,19 @@ expand_expr_real_1 (tree exp, rtx target
   }
 
 case CONST_DECL:
+  if (modifier == EXPAND_WRITE)
+   {
+ /* Writing into CONST_DECL is always invalid, but handle it
+gracefully.  */
+ addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (exp));
+ machine_mode address_mode = targetm.addr_space.address_mode (as);
+ op0 = expand_expr_addr_expr_1 (exp, NULL_RTX, address_mode,
+EXPAND_NORMAL, as);
+ op0 = memory_address_addr_space (mode, op0, as);
+ temp = gen_rtx_MEM (mode, op0);
+ set_mem_addr_space (temp, as);
+ return temp;
+   }
   return expand_expr (DECL_INITIAL (exp), target, VOIDmode, modifier);
 
 case REAL_CST:
--- gcc/testsuite/gfortran.dg/pr77959.f90.jj2016-10-13 11:57:30.019992471 
+0200
+++ gcc/testsuite/gfortran.dg/pr77959.f90   2016-10-13 11:58:50.719969914 
+0200
@@ -0,0 +1,16 @@
+! PR middle-end/77959
+! { dg-do compile }
+! { dg-options "-O2" }
+
+program pr77959
+  interface
+subroutine foo(x)  ! { dg-warning "Type mismatch in argument" }
+  real :: x
+end
+  end interface
+  call foo(1.0)
+end
+subroutine foo(x)
+  complex :: x
+  x = x + 1
+end

Jakub