diff options
author | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2015-01-21 22:01:24 +0000 |
---|---|---|
committer | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2015-01-21 22:01:24 +0000 |
commit | ffde65b31066f17eef243be882bb89a6e19370aa (patch) | |
tree | ea876d041c0a63eefccdac5416a8678e75da4cfc /gcc/fortran/trans-array.c | |
parent | a8c7acc4db08ce7c8ac3ddcb943f9219e2893792 (diff) | |
download | gcc-ffde65b31066f17eef243be882bb89a6e19370aa.tar.gz |
[.]
2015-01-21 Basile Starynkevitch <basile@starynkevitch.net>
{{merged with trunk -i.e. GCC5.0 in stage4- using
svn merge -r209216:219879 svn+ssh://bstarynk@gcc.gnu.org/svn/gcc/trunk
but should probably have used
svn merge -r209216:219879 ^/trunk
we don't use svnmerge.py anymore since our svn is version 1.8.10
}}
VERY UNSTABLE
2015-01-20 Basile Starynkevitch <basile@starynkevitch.net>
Move previous topdir ChangeLog.MELT to ChangeLog.MELT.2008-2014
[contrib/]
2015-01-21 Basile Starynkevitch <basile@starynkevitch.net>
* MELT-Plugin-Makefile: Able to make upgrade-melt as a
plugin. Works for GCC 5.0. Remove GCC 4.7 old stuff.
Move previous contrib/ChangeLog.MELT to ChangeLog.MELT.2008-2014
[gcc/]
2015-01-21 Basile Starynkevitch <basile@starynkevitch.net>
{{merged with trunk -i.e. GCC5.0 in stage4- using
svn merge -r209216:219879 svn+ssh://bstarynk@gcc.gnu.org/svn/gcc/trunk
but should probably have used
svn merge -r209216:219879 ^/trunk
**@@@ UNSTABLE since libmelt-ana-gimple.melt not compiling, but
translator painfully bootstrapping!!@@@@ }}
* toplev.c: Merged manually by keeping MELT extra stuff.
* toplev.h: Likewise.
* gengtype.c: Add "melt-runtime.h" in list, but merged with trunk.
* melt-runtime.h (MELT_VERSION_STRING): Bump to "1.2-pre-merged".
(meltgc_walk_gimple_seq): Remove.
(gt_ggc_mx_gimple_statement_d): Same for GCC 4.9 & 5.0
* melt-runtime.cc: Update copyright year.
(ggc_alloc_cleared_melt_valuevector_st, melt_resize_scangcvect):
Call ggc_internal_cleared_alloc.
(melt_val2passflag): Skip TODO_verify_ssa, TODO_verify_flow,
TODO_verify_stmts, TODO_verify_rtl_sharing for GCC 5.0.
(meltgc_walkstmt_cb, meltgc_walktree_cb)
(melt_tree_walk_frame_size, meltgc_walk_gimple_seq): Remove.
(melt_gt_ggc_mx_gimple_seq_d): Call
gt_ggc_mx_gimple_statement_base.
* melt-build-script.tpl: Update copyright year. Don't symlink
meltrunsup.h anymore.
* melt-build-script.sh: Regenerate.
* melt/warmelt-base.melt: Update copyright year.
(valdesc_object, valdesc_mapobjects, valdesc_mapstrings)
(valdesc_multiple, valdesc_closure, valdesc_routine, valdesc_hook)
(valdesc_bucketlongs, valdesc_jsonobject, valdesc_string)
(valdesc_strbuf, valdesc_pair, valdesc_list, valdesc_int)
(valdesc_double, valdesc_mixint, valdesc_mixloc)
(valdesc_mixbigint, valdesc_real, valdesc_special_data): Use
ggc_internal_alloc & ggc_internal_cleared_alloc for GCC 5.0.
(json_canonical_name): Use ISUPPER, ISALPHA, TOUPPER instead of
their standard <ctype.h> lowercase macros.
* melt/warmelt-modes.melt: Update copyright year.
(generate_runtypesupport_forwcopy_fun): Emit both GCC 4.9 & 5.0
compatible code.
* melt/libmelt-ana-base.melt: Update copyright year.
* melt/libmelt-ana-gimple.melt: TO BE IMPROVED
* melt/generated/*: Painfully regenerated several times thru GCC
4.9 MELT plugin.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/melt-branch@219975 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/fortran/trans-array.c')
-rw-r--r-- | gcc/fortran/trans-array.c | 240 |
1 files changed, 138 insertions, 102 deletions
diff --git a/gcc/fortran/trans-array.c b/gcc/fortran/trans-array.c index 8c4afb098bf..08b020b42a8 100644 --- a/gcc/fortran/trans-array.c +++ b/gcc/fortran/trans-array.c @@ -1,5 +1,5 @@ /* Array translation routines - Copyright (C) 2002-2014 Free Software Foundation, Inc. + Copyright (C) 2002-2015 Free Software Foundation, Inc. Contributed by Paul Brook <paul@nowt.org> and Steven Bosscher <s.bosscher@student.tudelft.nl> @@ -78,11 +78,22 @@ along with GCC; see the file COPYING3. If not see #include "config.h" #include "system.h" #include "coretypes.h" +#include "gfortran.h" +#include "hash-set.h" +#include "machmode.h" +#include "vec.h" +#include "double-int.h" +#include "input.h" +#include "alias.h" +#include "symtab.h" +#include "options.h" +#include "wide-int.h" +#include "inchash.h" #include "tree.h" +#include "fold-const.h" #include "gimple-expr.h" #include "diagnostic-core.h" /* For internal_error/fatal_error. */ #include "flags.h" -#include "gfortran.h" #include "constructor.h" #include "trans.h" #include "trans-stmt.h" @@ -90,6 +101,7 @@ along with GCC; see the file COPYING3. If not see #include "trans-array.h" #include "trans-const.h" #include "dependency.h" +#include "wide-int.h" static bool gfc_get_array_constructor_size (mpz_t *, gfc_constructor_base); @@ -297,8 +309,7 @@ gfc_conv_descriptor_token (tree desc) type = TREE_TYPE (desc); gcc_assert (GFC_DESCRIPTOR_TYPE_P (type)); - gcc_assert (GFC_TYPE_ARRAY_AKIND (type) == GFC_ARRAY_ALLOCATABLE); - gcc_assert (gfc_option.coarray == GFC_FCOARRAY_LIB); + gcc_assert (flag_coarray == GFC_FCOARRAY_LIB); field = gfc_advance_chain (TYPE_FIELDS (type), CAF_TOKEN_FIELD); /* Should be a restricted pointer - except in the finalization wrapper. */ @@ -830,7 +841,7 @@ gfc_trans_allocate_array_storage (stmtblock_t * pre, stmtblock_t * post, { /* Allocate the temporary. */ onstack = !dynamic && initial == NULL_TREE - && (gfc_option.flag_stack_arrays + && (flag_stack_arrays || gfc_can_put_var_on_stack (size)); if (onstack) @@ -1041,8 +1052,9 @@ gfc_trans_create_temp_array (stmtblock_t * pre, stmtblock_t * post, gfc_ss * ss, gcc_assert (ss->dimen > 0); gcc_assert (ss->loop->dimen == ss->dimen); - if (gfc_option.warn_array_temp && where) - gfc_warning ("Creating array temporary at %L", where); + if (warn_array_temporaries && where) + gfc_warning (OPT_Warray_temporaries, + "Creating array temporary at %L", where); /* Set the lower bound to zero. */ for (s = ss; s; s = s->parent) @@ -2045,11 +2057,15 @@ gfc_build_constant_array_constructor (gfc_expr * expr, tree type) TREE_CONSTANT (init) = 1; TREE_STATIC (init) = 1; - tmp = gfc_create_var (tmptype, "A"); + tmp = build_decl (input_location, VAR_DECL, create_tmp_var_name ("A"), + tmptype); + DECL_ARTIFICIAL (tmp) = 1; + DECL_IGNORED_P (tmp) = 1; TREE_STATIC (tmp) = 1; TREE_CONSTANT (tmp) = 1; TREE_READONLY (tmp) = 1; DECL_INITIAL (tmp) = init; + pushdecl (tmp); return tmp; } @@ -2794,11 +2810,11 @@ trans_array_bound_check (gfc_se * se, gfc_ss *ss, tree index, int n, tmp_up = gfc_conv_array_ubound (descriptor, n); if (name) - asprintf (&msg, "Index '%%ld' of dimension %d of array '%s' " - "outside of expected range (%%ld:%%ld)", n+1, name); + msg = xasprintf ("Index '%%ld' of dimension %d of array '%s' " + "outside of expected range (%%ld:%%ld)", n+1, name); else - asprintf (&msg, "Index '%%ld' of dimension %d " - "outside of expected range (%%ld:%%ld)", n+1); + msg = xasprintf ("Index '%%ld' of dimension %d " + "outside of expected range (%%ld:%%ld)", n+1); fault = fold_build2_loc (input_location, LT_EXPR, boolean_type_node, index, tmp_lo); @@ -2819,11 +2835,11 @@ trans_array_bound_check (gfc_se * se, gfc_ss *ss, tree index, int n, tmp_lo = gfc_conv_array_lbound (descriptor, n); if (name) - asprintf (&msg, "Index '%%ld' of dimension %d of array '%s' " - "below lower bound of %%ld", n+1, name); + msg = xasprintf ("Index '%%ld' of dimension %d of array '%s' " + "below lower bound of %%ld", n+1, name); else - asprintf (&msg, "Index '%%ld' of dimension %d " - "below lower bound of %%ld", n+1); + msg = xasprintf ("Index '%%ld' of dimension %d " + "below lower bound of %%ld", n+1); fault = fold_build2_loc (input_location, LT_EXPR, boolean_type_node, index, tmp_lo); @@ -3174,7 +3190,7 @@ gfc_conv_array_ref (gfc_se * se, gfc_array_ref * ar, gfc_expr *expr, && TREE_CODE (TREE_TYPE (se->expr)) == POINTER_TYPE) se->expr = build_fold_indirect_ref_loc (input_location, se->expr); - /* Use the actual tree type and not the wrapped coarray. */ + /* Use the actual tree type and not the wrapped coarray. */ if (!se->want_pointer) se->expr = fold_convert (TYPE_MAIN_VARIANT (TREE_TYPE (se->expr)), se->expr); @@ -3254,8 +3270,8 @@ gfc_conv_array_ref (gfc_se * se, gfc_array_ref * ar, gfc_expr *expr, cond = fold_build2_loc (input_location, LT_EXPR, boolean_type_node, indexse.expr, tmp); - asprintf (&msg, "Index '%%ld' of dimension %d of array '%s' " - "below lower bound of %%ld", n+1, var_name); + msg = xasprintf ("Index '%%ld' of dimension %d of array '%s' " + "below lower bound of %%ld", n+1, var_name); gfc_trans_runtime_check (true, false, cond, &se->pre, where, msg, fold_convert (long_integer_type_node, indexse.expr), @@ -3278,8 +3294,8 @@ gfc_conv_array_ref (gfc_se * se, gfc_array_ref * ar, gfc_expr *expr, cond = fold_build2_loc (input_location, GT_EXPR, boolean_type_node, indexse.expr, tmp); - asprintf (&msg, "Index '%%ld' of dimension %d of array '%s' " - "above upper bound of %%ld", n+1, var_name); + msg = xasprintf ("Index '%%ld' of dimension %d of array '%s' " + "above upper bound of %%ld", n+1, var_name); gfc_trans_runtime_check (true, false, cond, &se->pre, where, msg, fold_convert (long_integer_type_node, indexse.expr), @@ -3945,7 +3961,7 @@ done: continue; /* Catch allocatable lhs in f2003. */ - if (gfc_option.flag_realloc_lhs && ss->is_alloc_lhs) + if (flag_realloc_lhs && ss->is_alloc_lhs) continue; expr = ss_info->expr; @@ -3976,8 +3992,8 @@ done: /* Zero stride is not allowed. */ tmp = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, info->stride[dim], gfc_index_zero_node); - asprintf (&msg, "Zero stride is not allowed, for dimension %d " - "of array '%s'", dim + 1, expr_name); + msg = xasprintf ("Zero stride is not allowed, for dimension %d " + "of array '%s'", dim + 1, expr_name); gfc_trans_runtime_check (true, false, tmp, &inner, expr_loc, msg); free (msg); @@ -4034,9 +4050,9 @@ done: tmp2 = fold_build2_loc (input_location, TRUTH_AND_EXPR, boolean_type_node, non_zerosized, tmp2); - asprintf (&msg, "Index '%%ld' of dimension %d of array '%s' " - "outside of expected range (%%ld:%%ld)", - dim + 1, expr_name); + msg = xasprintf ("Index '%%ld' of dimension %d of array '%s' " + "outside of expected range (%%ld:%%ld)", + dim + 1, expr_name); gfc_trans_runtime_check (true, false, tmp, &inner, expr_loc, msg, fold_convert (long_integer_type_node, info->start[dim]), @@ -4056,9 +4072,9 @@ done: info->start[dim], lbound); tmp = fold_build2_loc (input_location, TRUTH_AND_EXPR, boolean_type_node, non_zerosized, tmp); - asprintf (&msg, "Index '%%ld' of dimension %d of array '%s' " - "below lower bound of %%ld", - dim + 1, expr_name); + msg = xasprintf ("Index '%%ld' of dimension %d of array '%s' " + "below lower bound of %%ld", + dim + 1, expr_name); gfc_trans_runtime_check (true, false, tmp, &inner, expr_loc, msg, fold_convert (long_integer_type_node, info->start[dim]), @@ -4088,9 +4104,9 @@ done: boolean_type_node, tmp, ubound); tmp3 = fold_build2_loc (input_location, TRUTH_AND_EXPR, boolean_type_node, non_zerosized, tmp3); - asprintf (&msg, "Index '%%ld' of dimension %d of array '%s' " - "outside of expected range (%%ld:%%ld)", - dim + 1, expr_name); + msg = xasprintf ("Index '%%ld' of dimension %d of array '%s' " + "outside of expected range (%%ld:%%ld)", + dim + 1, expr_name); gfc_trans_runtime_check (true, false, tmp2, &inner, expr_loc, msg, fold_convert (long_integer_type_node, tmp), @@ -4105,9 +4121,9 @@ done: } else { - asprintf (&msg, "Index '%%ld' of dimension %d of array '%s' " - "below lower bound of %%ld", - dim + 1, expr_name); + msg = xasprintf ("Index '%%ld' of dimension %d of array '%s' " + "below lower bound of %%ld", + dim + 1, expr_name); gfc_trans_runtime_check (true, false, tmp2, &inner, expr_loc, msg, fold_convert (long_integer_type_node, tmp), @@ -4134,9 +4150,9 @@ done: { tmp3 = fold_build2_loc (input_location, NE_EXPR, boolean_type_node, tmp, size[n]); - asprintf (&msg, "Array bound mismatch for dimension %d " - "of array '%s' (%%ld/%%ld)", - dim + 1, expr_name); + msg = xasprintf ("Array bound mismatch for dimension %d " + "of array '%s' (%%ld/%%ld)", + dim + 1, expr_name); gfc_trans_runtime_check (true, false, tmp3, &inner, expr_loc, msg, @@ -4344,12 +4360,19 @@ gfc_conv_resolve_dependencies (gfc_loopinfo * loop, gfc_ss * dest, if (ss->info->type != GFC_SS_SECTION) { - if (gfc_option.flag_realloc_lhs + if (flag_realloc_lhs && dest_expr != ss_expr && gfc_is_reallocatable_lhs (dest_expr) && ss_expr->rank) nDepend = gfc_check_dependency (dest_expr, ss_expr, true); + /* Check for cases like c(:)(1:2) = c(2)(2:3) */ + if (!nDepend && dest_expr->rank > 0 + && dest_expr->ts.type == BT_CHARACTER + && ss_expr->expr_type == EXPR_VARIABLE) + + nDepend = gfc_check_dependency (dest_expr, ss_expr, false); + continue; } @@ -5272,7 +5295,7 @@ gfc_array_allocate (gfc_se * se, gfc_expr * expr, tree status, tree errmsg, pointer = gfc_conv_descriptor_data_get (se->expr); STRIP_NOPS (pointer); - if (coarray && gfc_option.coarray == GFC_FCOARRAY_LIB) + if (coarray && flag_coarray == GFC_FCOARRAY_LIB) token = gfc_build_addr_expr (NULL_TREE, gfc_conv_descriptor_token (se->expr)); @@ -5296,7 +5319,7 @@ gfc_array_allocate (gfc_se * se, gfc_expr * expr, tree status, tree errmsg, gfc_add_expr_to_block (&se->pre, tmp); - /* Update the array descriptors. */ + /* Update the array descriptors. */ if (dimension) gfc_conv_descriptor_offset_set (&set_descriptor_block, se->expr, offset); @@ -5355,7 +5378,7 @@ gfc_array_deallocate (tree descriptor, tree pstat, tree errmsg, tree errlen, the allocation status may not be changed. */ tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node, var, build_int_cst (TREE_TYPE (var), 0)); - if (pstat != NULL_TREE && coarray && gfc_option.coarray == GFC_FCOARRAY_LIB) + if (pstat != NULL_TREE && coarray && flag_coarray == GFC_FCOARRAY_LIB) { tree cond; tree stat = build_fold_indirect_ref_loc (input_location, pstat); @@ -5380,9 +5403,8 @@ gfc_conv_array_initializer (tree type, gfc_expr * expr) { gfc_constructor *c; tree tmp; + offset_int wtmp; gfc_se se; - HOST_WIDE_INT hi; - unsigned HOST_WIDE_INT lo; tree index, range; vec<constructor_elt, va_gc> *v = NULL; @@ -5404,20 +5426,12 @@ gfc_conv_array_initializer (tree type, gfc_expr * expr) else gfc_conv_structure (&se, expr, 1); - tmp = TYPE_MAX_VALUE (TYPE_DOMAIN (type)); - gcc_assert (tmp && INTEGER_CST_P (tmp)); - hi = TREE_INT_CST_HIGH (tmp); - lo = TREE_INT_CST_LOW (tmp); - lo++; - if (lo == 0) - hi++; + wtmp = wi::to_offset (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) + 1; /* This will probably eat buckets of memory for large arrays. */ - while (hi != 0 || lo != 0) + while (wtmp != 0) { CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, se.expr); - if (lo == 0) - hi--; - lo--; + wtmp -= 1; } break; @@ -5430,11 +5444,11 @@ gfc_conv_array_initializer (tree type, gfc_expr * expr) { /* Problems occur when we get something like integer :: a(lots) = (/(i, i=1, lots)/) */ - gfc_fatal_error ("The number of elements in the array constructor " - "at %L requires an increase of the allowed %d " - "upper limit. See -fmax-array-constructor " - "option", &expr->where, - gfc_option.flag_max_array_constructor); + gfc_fatal_error ("The number of elements in the array " + "constructor at %L requires an increase of " + "the allowed %d upper limit. See " + "%<-fmax-array-constructor%> option", + &expr->where, flag_max_array_constructor); return NULL_TREE; } if (mpz_cmp_si (c->offset, 0) != 0) @@ -5704,7 +5718,7 @@ gfc_trans_auto_array_allocation (tree decl, gfc_symbol * sym, return; } - if (gfc_option.flag_stack_arrays) + if (flag_stack_arrays) { gcc_assert (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE); space = build_decl (sym->declared_at.lb->location, @@ -5925,8 +5939,9 @@ gfc_trans_dummy_array_bias (gfc_symbol * sym, tree tmpdesc, stride = gfc_index_one_node; - if (gfc_option.warn_array_temp) - gfc_warning ("Creating array temporary at %L", &loc); + if (warn_array_temporaries) + gfc_warning (OPT_Warray_temporaries, + "Creating array temporary at %L", &loc); } /* This is for the case where the array data is used directly without @@ -6009,8 +6024,8 @@ gfc_trans_dummy_array_bias (gfc_symbol * sym, tree tmpdesc, gfc_index_one_node, stride2); tmp = fold_build2_loc (input_location, NE_EXPR, gfc_array_index_type, temp, stride2); - asprintf (&msg, "Dimension %d of array '%s' has extent " - "%%ld instead of %%ld", n+1, sym->name); + msg = xasprintf ("Dimension %d of array '%s' has extent " + "%%ld instead of %%ld", n+1, sym->name); gfc_trans_runtime_check (true, false, tmp, &init, &loc, msg, fold_convert (long_integer_type_node, temp), @@ -6807,8 +6822,9 @@ gfc_conv_expr_descriptor (gfc_se *se, gfc_expr *expr) /* Set offset for assignments to pointer only to zero if it is not the full array. */ - if (se->direct_byref - && info->ref && info->ref->u.ar.type != AR_FULL) + if ((se->direct_byref || se->use_offset) + && ((info->ref && info->ref->u.ar.type != AR_FULL) + || (expr->expr_type == EXPR_ARRAY && se->use_offset))) base = gfc_index_zero_node; else if (GFC_ARRAY_TYPE_P (TREE_TYPE (desc))) base = gfc_evaluate_now (gfc_conv_array_offset (desc), &loop.pre); @@ -6893,13 +6909,13 @@ gfc_conv_expr_descriptor (gfc_se *se, gfc_expr *expr) stride, info->stride[n]); if (se->direct_byref - && info->ref - && info->ref->u.ar.type != AR_FULL) + && ((info->ref && info->ref->u.ar.type != AR_FULL) + || (expr->expr_type == EXPR_ARRAY && se->use_offset))) { base = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (base), base, stride); } - else if (GFC_ARRAY_TYPE_P (TREE_TYPE (desc))) + else if (GFC_ARRAY_TYPE_P (TREE_TYPE (desc)) || se->use_offset) { tmp = gfc_conv_array_lbound (desc, n); tmp = fold_build2_loc (input_location, MINUS_EXPR, @@ -6935,8 +6951,9 @@ gfc_conv_expr_descriptor (gfc_se *se, gfc_expr *expr) gfc_get_dataptr_offset (&loop.pre, parm, desc, offset, subref_array_target, expr); - if ((se->direct_byref || GFC_ARRAY_TYPE_P (TREE_TYPE (desc))) - && !se->data_not_needed) + if (((se->direct_byref || GFC_ARRAY_TYPE_P (TREE_TYPE (desc))) + && !se->data_not_needed) + || (se->use_offset && base != NULL_TREE)) { /* Set the offset. */ gfc_conv_descriptor_offset_set (&loop.pre, parm, base); @@ -7204,13 +7221,15 @@ gfc_conv_array_parameter (gfc_se * se, gfc_expr * expr, bool g77, } /* Repack the array. */ - if (gfc_option.warn_array_temp) + if (warn_array_temporaries) { if (fsym) - gfc_warning ("Creating array temporary at %L for argument '%s'", + gfc_warning (OPT_Warray_temporaries, + "Creating array temporary at %L for argument %qs", &expr->where, fsym->name); else - gfc_warning ("Creating array temporary at %L", &expr->where); + gfc_warning (OPT_Warray_temporaries, + "Creating array temporary at %L", &expr->where); } ptr = build_call_expr_loc (input_location, @@ -7263,7 +7282,7 @@ gfc_conv_array_parameter (gfc_se * se, gfc_expr * expr, bool g77, gfc_add_modify (&se->pre, new_field, old_field); } - if (gfc_option.coarray == GFC_FCOARRAY_LIB + if (flag_coarray == GFC_FCOARRAY_LIB && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (old_desc)) && GFC_TYPE_ARRAY_AKIND (TREE_TYPE (old_desc)) == GFC_ARRAY_ALLOCATABLE) @@ -7284,10 +7303,10 @@ gfc_conv_array_parameter (gfc_se * se, gfc_expr * expr, bool g77, char * msg; if (fsym && proc_name) - asprintf (&msg, "An array temporary was created for argument " - "'%s' of procedure '%s'", fsym->name, proc_name); + msg = xasprintf ("An array temporary was created for argument " + "'%s' of procedure '%s'", fsym->name, proc_name); else - asprintf (&msg, "An array temporary was created"); + msg = xasprintf ("An array temporary was created"); tmp = build_fold_indirect_ref_loc (input_location, desc); @@ -7387,8 +7406,8 @@ gfc_trans_dealloc_allocated (tree descriptor, bool coarray, gfc_expr *expr) /* This helper function calculates the size in words of a full array. */ -static tree -get_full_array_size (stmtblock_t *block, tree decl, int rank) +tree +gfc_full_array_size (stmtblock_t *block, tree decl, int rank) { tree idx; tree nelems; @@ -7414,7 +7433,7 @@ get_full_array_size (stmtblock_t *block, tree decl, int rank) static tree duplicate_allocatable (tree dest, tree src, tree type, int rank, - bool no_malloc, tree str_sz) + bool no_malloc, bool no_memcpy, tree str_sz) { tree tmp; tree size; @@ -7448,9 +7467,13 @@ duplicate_allocatable (tree dest, tree src, tree type, int rank, gfc_add_expr_to_block (&block, tmp); } - tmp = builtin_decl_explicit (BUILT_IN_MEMCPY); - tmp = build_call_expr_loc (input_location, tmp, 3, dest, src, - fold_convert (size_type_node, size)); + if (!no_memcpy) + { + tmp = builtin_decl_explicit (BUILT_IN_MEMCPY); + tmp = build_call_expr_loc (input_location, tmp, 3, dest, src, + fold_convert (size_type_node, size)); + gfc_add_expr_to_block (&block, tmp); + } } else { @@ -7459,7 +7482,7 @@ duplicate_allocatable (tree dest, tree src, tree type, int rank, gfc_init_block (&block); if (rank) - nelems = get_full_array_size (&block, src, rank); + nelems = gfc_full_array_size (&block, src, rank); else nelems = gfc_index_one_node; @@ -7479,14 +7502,17 @@ duplicate_allocatable (tree dest, tree src, tree type, int rank, /* We know the temporary and the value will be the same length, so can use memcpy. */ - tmp = builtin_decl_explicit (BUILT_IN_MEMCPY); - tmp = build_call_expr_loc (input_location, - tmp, 3, gfc_conv_descriptor_data_get (dest), - gfc_conv_descriptor_data_get (src), - fold_convert (size_type_node, size)); + if (!no_memcpy) + { + tmp = builtin_decl_explicit (BUILT_IN_MEMCPY); + tmp = build_call_expr_loc (input_location, tmp, 3, + gfc_conv_descriptor_data_get (dest), + gfc_conv_descriptor_data_get (src), + fold_convert (size_type_node, size)); + gfc_add_expr_to_block (&block, tmp); + } } - gfc_add_expr_to_block (&block, tmp); tmp = gfc_finish_block (&block); /* Null the destination if the source is null; otherwise do @@ -7508,7 +7534,8 @@ duplicate_allocatable (tree dest, tree src, tree type, int rank, tree gfc_duplicate_allocatable (tree dest, tree src, tree type, int rank) { - return duplicate_allocatable (dest, src, type, rank, false, NULL_TREE); + return duplicate_allocatable (dest, src, type, rank, false, false, + NULL_TREE); } @@ -7517,7 +7544,16 @@ gfc_duplicate_allocatable (tree dest, tree src, tree type, int rank) tree gfc_copy_allocatable_data (tree dest, tree src, tree type, int rank) { - return duplicate_allocatable (dest, src, type, rank, true, NULL_TREE); + return duplicate_allocatable (dest, src, type, rank, true, false, + NULL_TREE); +} + +/* Allocate dest to the same size as src, but don't copy anything. */ + +tree +gfc_duplicate_allocatable_nocopy (tree dest, tree src, tree type, int rank) +{ + return duplicate_allocatable (dest, src, type, rank, false, true, NULL_TREE); } @@ -7577,7 +7613,7 @@ structure_alloc_comps (gfc_symbol * der_type, tree decl, /* Use the descriptor for an allocatable array. Since this is a full array reference, we only need the descriptor information from dimension = rank. */ - tmp = get_full_array_size (&fnblock, decl, rank); + tmp = gfc_full_array_size (&fnblock, decl, rank); tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type, tmp, gfc_index_one_node); @@ -7756,7 +7792,7 @@ structure_alloc_comps (gfc_symbol * der_type, tree decl, break; case NULLIFY_ALLOC_COMP: - if (c->attr.pointer) + if (c->attr.pointer || c->attr.proc_pointer) continue; else if (c->attr.allocatable && (c->attr.dimension|| c->attr.codimension)) @@ -7936,7 +7972,7 @@ structure_alloc_comps (gfc_symbol * der_type, tree decl, gfc_add_expr_to_block (&fnblock, tmp); size = size_of_string_in_bytes (c->ts.kind, len); tmp = duplicate_allocatable (dcmp, comp, ctype, rank, - false, size); + false, false, size); gfc_add_expr_to_block (&fnblock, tmp); } else if (c->attr.allocatable && !c->attr.proc_pointer @@ -8464,7 +8500,7 @@ gfc_alloc_allocatable_for_assignment (gfc_loopinfo *loop, size2 = gfc_evaluate_now (size2, &fblock); /* Realloc expression. Note that the scalarizer uses desc.data - in the array reference - (*desc.data)[<element>]. */ + in the array reference - (*desc.data)[<element>]. */ gfc_init_block (&realloc_block); if ((expr1->ts.type == BT_DERIVED) @@ -8633,8 +8669,8 @@ gfc_trans_deferred_array (gfc_symbol * sym, gfc_wrapped_block * block) type = TREE_TYPE (descriptor); } - /* NULLIFY the data pointer. */ - if (GFC_DESCRIPTOR_TYPE_P (type) && !sym->attr.save) + /* NULLIFY the data pointer, for non-saved allocatables. */ + if (GFC_DESCRIPTOR_TYPE_P (type) && !sym->attr.save && sym->attr.allocatable) gfc_conv_descriptor_data_set (&init, descriptor, null_pointer_node); gfc_restore_backend_locus (&loc); @@ -9078,7 +9114,7 @@ gfc_walk_subexpr (gfc_ss * ss, gfc_expr * expr) break; default: - internal_error ("bad expression type during walk (%d)", + gfc_internal_error ("bad expression type during walk (%d)", expr->expr_type); } return ss; |