This is the mail archive of the fortran@gcc.gnu.org mailing list for the GNU Fortran project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

optimization removes a __builtin_memcpy?


First, I'll preface this with "I'm probably doing something wrong."
I'm adding support to gfortran for the ERRMSG argument to [DE]ALLOCATE.
Here's, some code to demonstrate:

program a
   call works
   call fails
end program a
!
! Work with all optimization levels.
!
subroutine works
   character(len=70) :: err = 'No error'
   integer, allocatable :: i(:)
   allocate(i(4), errmsg=err)          ! err is unchanged.
   print *, err
   deallocate(i)
   allocate(i(4), i(5), errmsg=err)    ! err is assigned an error message.
   print *, err
end subroutine works
!
! Fails at -O[123] due to len=30, works with -O0.
!
subroutine fails
   character(len=30) :: err = 'No error'
   integer, allocatable :: i(:)
   allocate(i(4), errmsg=err)
   print *, err
   deallocate(i)
   allocate(i(4), i(5), errmsg=err)
   print *, err
end subroutine fails

kargl[222] gfc4x -o z -fdump-tree-original a.f90
kargl[223] ./z
 No error                                                              
 Attempt to deallocate an unallocated object                          
 No error                      
 Attempt to deallocate an unall
kargl[224] mv a.f90.003t.original abc
kargl[225] gfc4x -o z -fdump-tree-original -O a.f90
a.f90: In function 'fails':
a.f90:16: error: non-trivial conversion at assignment
character(kind=1) *
character(kind=1)[1:30]
iftmp.17 = err;

a.f90:16: error: non-trivial conversion at assignment
character(kind=1) *
character(kind=1)[1:30]
iftmp.20 = err;

a.f90:16: internal compiler error: verify_gimple failed
Please submit a full bug report,
with preprocessed source if appropriate.
See <http://gcc.gnu.org/bugs.html> for instructions.

Looking at a diff of the two -fdump-tree-original outputs shows:

     ERRMSG.12 = &"Attempt to deallocate an unallocated object"[1]{lb: 1 sz: 1};
-    ERRMSG.12 = stat.11 != 0 ? (void) __builtin_memcpy ((void *) &err, (void *) ERRMSG.12, 30) : (void) 0;
+    ERRMSG.12 = stat.11 != 0 ? err = *(character(kind=1)[1:30] * {ref-all}) ERRMSG.12 : (void) 0;

The chunk of code that I've add to trans-stmt.c(gfc_trans_deallocate) looks like

	  /* A better error message may be possible, but not required.  */
	  const char *msg = "Attempt to deallocate an unallocated object";
	  tree errmsg, slen, dlen;

	  gfc_init_se (&se, NULL);
	  gfc_conv_expr_lhs (&se, code->expr);

	  errmsg = gfc_create_var (pchar_type_node, "ERRMSG");
 
      /* astat is >= 0.  */
	  tmp = fold_build2 (NE_EXPR, boolean_type_node, astat,
			     build_int_cst (TREE_TYPE (astat), 0));

      /* Create tree for msg.  */
	  gfc_add_modify (&block, errmsg,
               gfc_build_addr_expr (pchar_type_node,
                        gfc_build_localized_cstring_const (msg)));

      /* Don't overflow the string.  slen = min(dlen, len).  */
	  slen = build_int_cst (gfc_charlen_type_node, 44);
	  dlen = gfc_get_expr_charlen (code->expr);
	  slen = fold_build2 (MIN_EXPR, TREE_TYPE (slen), dlen, slen);

	  tmp = fold_build3 (COND_EXPR, pchar_type_node, tmp, 
		build_call_expr (built_in_decls[BUILT_IN_MEMCPY], 3,
		se.expr, errmsg, slen),
	        build_empty_stmt ());

	  gfc_add_modify (&block, errmsg, tmp);

The diff shows that the fails case correctly has dlen=30
and in fact for any value less than slen=44 and -O[123]
removes the __builtin_memcpy().  So what is missing or
how to I inhibit this optimization?

-- 
Steve


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]