Patchwork [Fortran] PR50718 Fix -fcheck=pointer 4.6/4.7 regression

login
register
mail settings
Submitter Tobias Burnus
Date Oct. 14, 2011, 10:19 a.m.
Message ID <4E980CC7.40902@net-b.de>
Download mbox | patch
Permalink /patch/119764/
State New
Headers show

Comments

Tobias Burnus - Oct. 14, 2011, 10:19 a.m.
Hello,

while testing my constructor draft patch with FGSL, I found two bugs 
(4.6/4.7 regressions): PR target/50721 (segfault on x86-64 after 
execution - one of the rare -O0 only bugs) - and while trying to debug 
it, I found this bug.

The problem is that for -fcheck=pointer, gfortran expects a pointer for 
the "if (actual_arg == NULL)" check; however, if the dummy has the VALUE 
attribute, one has "*actual_arg". The solution is to strip off the "*" 
for the pointer check. Without the patch, one gets an ICE when comparing 
a derived type (instead of a pointer to a DT) with NULL.

While writing the test case, I realized that there is also the %VAL() 
method of generating a nonpointer should be also tested for. As the 
actual argument in the test case (*_12.f90) is not a record type (DT) 
but a simple integer, comparing "%VAL(p) == NULL" works (but is bogus). 
Result without the patch: Segfault at run time instead of an ICE. With 
the patch, one gets the nice  run-time error message.

Build and regtested on x86-64-linux.
OK for the trunk and 4.6?

Tobias

PS: *Pre-ping* for the pending review of as simple documentation/flag 
patch: http://gcc.gnu.org/ml/fortran/2011-10/msg00073.html
Tobias Burnus - Oct. 14, 2011, 3:17 p.m.
On 10/14/2011 12:19 PM, Tobias Burnus wrote:
> while testing my constructor draft patch with FGSL, I found two bugs 
> (4.6/4.7 regressions): PR target/50721 (segfault on x86-64 after 
> execution - one of the rare -O0 only bugs)

That bug turned out to be a out-of-bounds problem between Fortran and C, 
which is very difficult to diagnose, and that the stack was destroyed, 
didn't help. As Bernd pointed out, the bug is in the Fortran programm 
(FGSL's poly.f90) and not in the compiler.

Regarding the true GCC bug: The patch for -fcheck=pointer was approved 
off list by Janus. I have committed the trunk version as Rev. 179988. I 
will soon backport it for 4.6 - in time for the 4.6.2 release, which is 
to be expected next week.

If you think any other 4.6 regression should be fixed in 4.6.2: Well, 
you have the whole weekend to work on a patch :-)

Tobias

Patch

2011-10-14  Tobias Burnus  <burnus@net-b.de>

	PR fortran/50718
	* trans-expr.c (gfc_conv_procedure_call): Fix -fcheck=pointer
	for dummy arguments with VALUE attribute.

2011-10-14  Tobias Burnus  <burnus@net-b.de>

	PR fortran/50718
	* gfortran.dg/pointer_check_11.f90: New.
	* gfortran.dg/pointer_check_12.f90: New.

diff --git a/gcc/fortran/trans-expr.c b/gcc/fortran/trans-expr.c
index ca0523f..a3847aa 100644
--- a/gcc/fortran/trans-expr.c
+++ b/gcc/fortran/trans-expr.c
@@ -3357,10 +3357,16 @@  gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
 	      else
 		goto end_pointer_check;
 
+	      tmp = parmse.expr;
+
+	      /* If the argument is passed by value, we need to strip the
+		 INDIRECT_REF.  */
+	      if (!POINTER_TYPE_P (TREE_TYPE (parmse.expr)))
+		tmp = gfc_build_addr_expr (NULL_TREE, tmp);
 
 	      cond = fold_build2_loc (input_location, EQ_EXPR,
-				      boolean_type_node, parmse.expr,
-				      fold_convert (TREE_TYPE (parmse.expr),
+				      boolean_type_node, tmp,
+				      fold_convert (TREE_TYPE (tmp),
 						    null_pointer_node));
 	    }
  
--- /dev/null	2011-10-14 07:41:04.295638041 +0200
+++ gcc/gcc/testsuite/gfortran.dg/pointer_check_11.f90	2011-10-14 09:33:41.000000000 +0200
@@ -0,0 +1,24 @@ 
+! { dg-do run }
+! { dg-options "-fcheck=all" }
+!
+! { dg-shouldfail "Pointer check" }
+! { dg-output "Fortran runtime error: Pointer actual argument 'y' is not associated" }
+!
+!
+! PR fortran/50718
+!
+! Was failing (ICE) with -fcheck=pointer if the dummy had the value attribute.
+
+type t
+  integer :: p
+end type t
+
+type(t), pointer :: y => null()
+
+call sub(y) ! Invalid: Nonassociated pointer
+
+contains
+  subroutine sub (x)
+    type(t), value :: x
+  end subroutine
+end
--- /dev/null	2011-10-14 07:41:04.295638041 +0200
+++ gcc/gcc/testsuite/gfortran.dg/pointer_check_12.f90	2011-10-14 09:42:53.000000000 +0200
@@ -0,0 +1,22 @@ 
+! { dg-do run }
+! { dg-options "-fcheck=all" }
+!
+! { dg-shouldfail "Pointer check" }
+! { dg-output "Fortran runtime error: Pointer actual argument 'p' is not associated" }
+!
+! PR fortran/50718
+!
+! Was failing with -fcheck=pointer: Segfault at run time
+
+integer, pointer :: p => null()
+
+call sub2(%val(p)) ! Invalid: Nonassociated pointer
+end
+
+! Not quite correct dummy, but if one uses VALUE, gfortran
+! complains about a missing interface - which we cannot use
+! if we want to use %VAL().
+
+subroutine sub2(p)
+  integer :: p
+end subroutine sub2