aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran/simplify.c
diff options
context:
space:
mode:
authorThomas Koenig <tkoenig@gcc.gnu.org>2011-08-05 21:51:59 +0000
committerThomas Koenig <tkoenig@gcc.gnu.org>2011-08-05 21:51:59 +0000
commit86dbed7d1bbbee6c0a5304091e089c48a20c0142 (patch)
tree355e022c7c1cbec05a02dc85dd3da5320674d598 /gcc/fortran/simplify.c
parent7cfea2ef26a3aab320c90d71c35c69a8c78404d7 (diff)
downloadgcc-86dbed7d1bbbee6c0a5304091e089c48a20c0142.zip
gcc-86dbed7d1bbbee6c0a5304091e089c48a20c0142.tar.gz
gcc-86dbed7d1bbbee6c0a5304091e089c48a20c0142.tar.bz2
re PR fortran/37211 (TRANSFER to characters: Size checking)
2011-08-05 Thomas Koenig <tkoenig@gcc.gnu.org> PR fortran/37221 * gfortran.h (gfc_calculate_transfer_sizes): Add prototype. * target-memory.h (gfc_target_interpret_expr): Add boolean argument wether to convert wide characters. * target-memory.c (gfc_target_expr_size): Also return length of characters for non-constant expressions if these can be determined from the cl. (interpret_array): Add argument for gfc_target_interpret_expr. (gfc_interpret_derived): Likewise. (gfc_target_interpret_expr): Likewise. * check.c: Include target-memory.h. (gfc_calculate_transfer_sizes): New function. (gfc_check_transfer): When -Wsurprising is in force, calculate sizes and warn if result is larger than size (check moved from gfc_simplify_transfer). * simplify.c (gfc_simplify_transfer): Use gfc_calculate_transfer_sizes. Remove warning. 2011-08-05 Thomas Koenig <tkoenig@gcc.gnu.org> PR fortran/37221 * gfortran.dg/transfer_check_2.f90: New test case. From-SVN: r177486
Diffstat (limited to 'gcc/fortran/simplify.c')
-rw-r--r--gcc/fortran/simplify.c38
1 files changed, 6 insertions, 32 deletions
diff --git a/gcc/fortran/simplify.c b/gcc/fortran/simplify.c
index 79b383a..e4ffc3b 100644
--- a/gcc/fortran/simplify.c
+++ b/gcc/fortran/simplify.c
@@ -6028,17 +6028,19 @@ gfc_simplify_transfer (gfc_expr *source, gfc_expr *mold, gfc_expr *size)
gfc_expr *mold_element;
size_t source_size;
size_t result_size;
- size_t result_elt_size;
size_t buffer_size;
mpz_t tmp;
unsigned char *buffer;
+ size_t result_length;
+
if (!gfc_is_constant_expr (source)
|| (gfc_init_expr_flag && !gfc_is_constant_expr (mold))
|| !gfc_is_constant_expr (size))
return NULL;
- if (source->expr_type == EXPR_FUNCTION)
+ if (gfc_calculate_transfer_sizes (source, mold, size, &source_size,
+ &result_size, &result_length) == FAILURE)
return NULL;
/* Calculate the size of the source. */
@@ -6064,44 +6066,16 @@ gfc_simplify_transfer (gfc_expr *source, gfc_expr *mold, gfc_expr *size)
result->value.character.length = mold_element->value.character.length;
/* Set the number of elements in the result, and determine its size. */
- result_elt_size = gfc_target_expr_size (mold_element);
- if (result_elt_size == 0)
- {
- gfc_free_expr (result);
- return NULL;
- }
if (mold->expr_type == EXPR_ARRAY || mold->rank || size)
{
- int result_length;
-
result->expr_type = EXPR_ARRAY;
result->rank = 1;
-
- if (size)
- result_length = (size_t)mpz_get_ui (size->value.integer);
- else
- {
- result_length = source_size / result_elt_size;
- if (result_length * result_elt_size < source_size)
- result_length += 1;
- }
-
result->shape = gfc_get_shape (1);
mpz_init_set_ui (result->shape[0], result_length);
-
- result_size = result_length * result_elt_size;
}
else
- {
- result->rank = 0;
- result_size = result_elt_size;
- }
-
- if (gfc_option.warn_surprising && source_size < result_size)
- gfc_warning("Intrinsic TRANSFER at %L has partly undefined result: "
- "source size %ld < result size %ld", &source->where,
- (long) source_size, (long) result_size);
+ result->rank = 0;
/* Allocate the buffer to store the binary version of the source. */
buffer_size = MAX (source_size, result_size);
@@ -6112,7 +6086,7 @@ gfc_simplify_transfer (gfc_expr *source, gfc_expr *mold, gfc_expr *size)
gfc_target_encode_expr (source, buffer, buffer_size);
/* And read the buffer back into the new expression. */
- gfc_target_interpret_expr (buffer, buffer_size, result);
+ gfc_target_interpret_expr (buffer, buffer_size, result, false);
return result;
}