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
2011-10-14 Tobias Burnus <bur...@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 <bur...@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