On October 14, 2016 7:20:43 PM GMT+02:00, Jakub Jelinek <ja...@redhat.com> wrote: >Hi! > >The following (invalid) testcase ICEs, because we try to store into >CONST_DECL's FIELD. Normally in GIMPLE we have MEM_REF[&C.1234] 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 <ja...@redhat.com> > > PR middle-end/77959 > * expr.c (expand_expr_real_1) <case CONST_DECL>: For EXPAND_WRITE > return a MEM. > > * gfortran.dg/pr77959.f90: New test. > >--- gcc/expr.c.jj 2016-10-09 13:19:09.000000000 +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