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