Fix Fortran ICE in tree-nested.c (PR fortran/92781)
diff mbox series

Message ID 20191205081036.GO10088@tucnak
State New
Headers show
Series
  • Fix Fortran ICE in tree-nested.c (PR fortran/92781)
Related show

Commit Message

Jakub Jelinek Dec. 5, 2019, 8:10 a.m. UTC
Hi!

In the following testcase, sym is the current function, we have created
earlier .__result as the PARM_DECL containing pointer to the length to be
returned and ..__result is a local VAR_DECL which contains the string length
inside of the function and is at the end copied to *.__result.

The reason this ICEs in tree-nested.c is that DECL_CONTEXT of that automatic
..__result variable is NULL, rather than the expected context of the current
function.  This happens because we attempt to add it to the parent function
(which there isn't any), so DECL_CONTEXT is NULL.

The following patch fixes that, bootstrapped/regtested on x86_64-linux and
i686-linux, ok for trunk?

2019-12-05  Jakub Jelinek  <jakub@redhat.com>

	PR fortran/92781
	* trans-decl.c (gfc_get_symbol_decl): If sym->backend_decl is
	current_function_decl, add length to current rather than parent
	function and expect DECL_CONTEXT (length) to be current_function_decl.

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


	Jakub

Comments

Tobias Burnus Dec. 5, 2019, 8:13 a.m. UTC | #1
On 12/5/19 9:10 AM, Jakub Jelinek wrote:
> In the following testcase, sym is the current function, we have created
> earlier .__result as the PARM_DECL containing pointer to the length to be
> returned and ..__result is a local VAR_DECL which contains the string length
> inside of the function and is at the end copied to *.__result.
>
> The reason this ICEs in tree-nested.c is that DECL_CONTEXT of that automatic
> ..__result variable is NULL, rather than the expected context of the current
> function.  This happens because we attempt to add it to the parent function
> (which there isn't any), so DECL_CONTEXT is NULL.
>
> The following patch fixes that, bootstrapped/regtested on x86_64-linux and
> i686-linux, ok for trunk?

LGTM – thanks for the patch!

Tobias

> 2019-12-05  Jakub Jelinek  <jakub@redhat.com>
>
> 	PR fortran/92781
> 	* trans-decl.c (gfc_get_symbol_decl): If sym->backend_decl is
> 	current_function_decl, add length to current rather than parent
> 	function and expect DECL_CONTEXT (length) to be current_function_decl.
>
> 	* gfortran.dg/pr92781.f90: New test.
>
> --- gcc/fortran/trans-decl.c.jj	2019-11-11 21:04:05.000000000 +0100
> +++ gcc/fortran/trans-decl.c	2019-12-04 12:32:58.489578829 +0100
> @@ -1631,15 +1631,18 @@ gfc_get_symbol_decl (gfc_symbol * sym)
>   	      /* Add the string length to the same context as the symbol.  */
>   	      if (DECL_CONTEXT (length) == NULL_TREE)
>   		{
> -		  if (DECL_CONTEXT (sym->backend_decl)
> -		      == current_function_decl)
> +		  if (sym->backend_decl == current_function_decl
> +		      || (DECL_CONTEXT (sym->backend_decl)
> +			  == current_function_decl))
>   		    gfc_add_decl_to_function (length);
>   		  else
>   		    gfc_add_decl_to_parent_function (length);
>   		}
>   
> -	      gcc_assert (DECL_CONTEXT (sym->backend_decl)
> -			  == DECL_CONTEXT (length));
> +	      gcc_assert (sym->backend_decl == current_function_decl
> +			  ? DECL_CONTEXT (length) == current_function_decl
> +			  : (DECL_CONTEXT (sym->backend_decl)
> +			     == DECL_CONTEXT (length)));
>   
>   	      gfc_defer_symbol_init (sym);
>   	    }
> --- gcc/testsuite/gfortran.dg/pr92781.f90.jj	2019-12-04 12:42:39.063598013 +0100
> +++ gcc/testsuite/gfortran.dg/pr92781.f90	2019-12-04 12:42:20.032891766 +0100
> @@ -0,0 +1,11 @@
> +! PR fortran/92781
> +! { dg-do compile }
> +
> +function foo ()
> +  character(:), allocatable :: foo
> +  call bar ()
> +  foo = 'abc'
> +contains
> +  subroutine bar
> +  end
> +end
>
> 	Jakub
>

Patch
diff mbox series

--- gcc/fortran/trans-decl.c.jj	2019-11-11 21:04:05.000000000 +0100
+++ gcc/fortran/trans-decl.c	2019-12-04 12:32:58.489578829 +0100
@@ -1631,15 +1631,18 @@  gfc_get_symbol_decl (gfc_symbol * sym)
 	      /* Add the string length to the same context as the symbol.  */
 	      if (DECL_CONTEXT (length) == NULL_TREE)
 		{
-		  if (DECL_CONTEXT (sym->backend_decl)
-		      == current_function_decl)
+		  if (sym->backend_decl == current_function_decl
+		      || (DECL_CONTEXT (sym->backend_decl)
+			  == current_function_decl))
 		    gfc_add_decl_to_function (length);
 		  else
 		    gfc_add_decl_to_parent_function (length);
 		}
 
-	      gcc_assert (DECL_CONTEXT (sym->backend_decl)
-			  == DECL_CONTEXT (length));
+	      gcc_assert (sym->backend_decl == current_function_decl
+			  ? DECL_CONTEXT (length) == current_function_decl
+			  : (DECL_CONTEXT (sym->backend_decl)
+			     == DECL_CONTEXT (length)));
 
 	      gfc_defer_symbol_init (sym);
 	    }
--- gcc/testsuite/gfortran.dg/pr92781.f90.jj	2019-12-04 12:42:39.063598013 +0100
+++ gcc/testsuite/gfortran.dg/pr92781.f90	2019-12-04 12:42:20.032891766 +0100
@@ -0,0 +1,11 @@ 
+! PR fortran/92781
+! { dg-do compile }
+
+function foo ()
+  character(:), allocatable :: foo
+  call bar ()
+  foo = 'abc'
+contains
+  subroutine bar
+  end
+end