diff options
author | Andrew Pinski <pinskia@gmail.com> | 2006-11-25 13:43:48 -0800 |
---|---|---|
committer | Andrew Pinski <pinskia@gcc.gnu.org> | 2006-11-25 13:43:48 -0800 |
commit | 85d6cbd388a26cc9ed4f2538c8c1835597e1aed8 (patch) | |
tree | ccee1801f6d73f965a89221a4a0fc6639305f76e /gcc | |
parent | 56d8eb6260b8c8f9e65b40348384e9b28c03f3ce (diff) | |
download | gcc-85d6cbd388a26cc9ed4f2538c8c1835597e1aed8.zip gcc-85d6cbd388a26cc9ed4f2538c8c1835597e1aed8.tar.gz gcc-85d6cbd388a26cc9ed4f2538c8c1835597e1aed8.tar.bz2 |
re PR fortran/29951 (incorrect conversion from string to integer by TRANSFER())
2006-11-25 Andrew Pinski <pinskia@gmail.com>
PR fortran/29951
* trans-intrinsic.c (gfc_conv_intrinsic_transfer): Change to
call memcpy instead of creating a VIEW_CONVERT_EXRP.
2006-11-25 Andrew Pinski <pinskia@gmail.com>
PR fortran/29951
* gfortran.fortran-torture/execute/transfer2.f90: New test
From-SVN: r119211
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/fortran/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/fortran/trans-intrinsic.c | 22 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gfortran.fortran-torture/execute/transfer2.f90 | 19 |
4 files changed, 49 insertions, 3 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 86710de..cf78797 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,9 @@ +2006-11-25 Andrew Pinski <pinskia@gmail.com> + + PR fortran/29951 + * trans-intrinsic.c (gfc_conv_intrinsic_transfer): Change to + call memcpy instead of creating a VIEW_CONVERT_EXRP. + 2006-11-25 Francois-Xavier Coudert <coudert@clipper.ens.fr> PR fortran/29711 diff --git a/gcc/fortran/trans-intrinsic.c b/gcc/fortran/trans-intrinsic.c index 5facd5b..9256e86 100644 --- a/gcc/fortran/trans-intrinsic.c +++ b/gcc/fortran/trans-intrinsic.c @@ -2989,7 +2989,7 @@ gfc_conv_intrinsic_array_transfer (gfc_se * se, gfc_expr * expr) /* Scalar transfer statement. - TRANSFER (source, mold) = VIEW_CONVERT_EXPR<typeof<mold> >source. */ + TRANSFER (source, mold) = memcpy(&tmpdecl, &source, size), tmpdecl. */ static void gfc_conv_intrinsic_transfer (gfc_se * se, gfc_expr * expr) @@ -2999,6 +2999,7 @@ gfc_conv_intrinsic_transfer (gfc_se * se, gfc_expr * expr) tree type; tree ptr; gfc_ss *ss; + tree tmpdecl, tmp, args; /* Get a pointer to the source. */ arg = expr->value.function.actual; @@ -3014,6 +3015,7 @@ gfc_conv_intrinsic_transfer (gfc_se * se, gfc_expr * expr) arg = arg->next; type = gfc_typenode_for_spec (&expr->ts); + if (expr->ts.type == BT_CHARACTER) { ptr = convert (build_pointer_type (type), ptr); @@ -3026,8 +3028,22 @@ gfc_conv_intrinsic_transfer (gfc_se * se, gfc_expr * expr) } else { - tree tmp = build_fold_indirect_ref (ptr); - se->expr = fold_build1 (VIEW_CONVERT_EXPR, type, tmp); + tree moldsize; + tmpdecl = gfc_create_var (type, "transfer"); + moldsize = size_in_bytes (type); + + /* Use memcpy to do the transfer. */ + tmp = build1 (ADDR_EXPR, build_pointer_type (type), tmpdecl); + tmp = fold_convert (pvoid_type_node, tmp); + args = gfc_chainon_list (NULL_TREE, tmp); + tmp = fold_convert (pvoid_type_node, ptr); + args = gfc_chainon_list (args, tmp); + args = gfc_chainon_list (args, moldsize); + tmp = built_in_decls[BUILT_IN_MEMCPY]; + tmp = build_function_call_expr (tmp, args); + gfc_add_expr_to_block (&se->pre, tmp); + + se->expr = tmpdecl; } } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a834a60..ccb3774 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2006-11-25 Andrew Pinski <pinskia@gmail.com> + + PR fortran/29951 + * gfortran.fortran-torture/execute/transfer2.f90: New test. + 2006-11-25 Francois-Xavier Coudert <coudert@clipper.ens.fr> * gfortran.fortran-torture/execute/specifics.f90: Remove test diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/transfer2.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/transfer2.f90 new file mode 100644 index 0000000..b57841c --- /dev/null +++ b/gcc/testsuite/gfortran.fortran-torture/execute/transfer2.f90 @@ -0,0 +1,19 @@ +program test_convert + + implicit none + character(len=4) :: byte_string + character(len=1),dimension(4) :: byte_array + integer*4 :: value,value1,n,i + + byte_string(1:1) = char(157) + byte_string(2:2) = char(127) + byte_string(3:3) = char(100) + byte_string(4:4) = char(0) + + byte_array(1:4) = (/char(157),char(127),char(100),char(0)/) + + value = transfer(byte_string(1:4),value) + value1 = transfer(byte_array(1:4),value1) + + if (value .ne. value1) call abort() +end program test_convert |