http://gcc.gnu.org/bugzilla/show_bug.cgi?id=44352
Tobias Burnus <burnus at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |burnus at gcc dot gnu.org --- Comment #9 from Tobias Burnus <burnus at gcc dot gnu.org> 2010-12-07 09:45:52 UTC --- (In reply to comment #8) > The ICE arises because the result string is not POINTER_TYPE_P in spite of > line trans-expr.c:3965 > tmp = gfc_build_addr_expr (build_pointer_type (type), tmp); Well, that's a different string. If one looks at the dump (with the patch) for 'h ' and a length-3 string: __builtin_memcpy ((void *) &dname.1, (void *) "h ", 2); __builtin_memset ((void *) &dname.1 + 2, 32, 1); __builtin_memmove ((void *) &ddname, (void *) &dname.1, 3); Thus, one first assigns to the statement-function variable ("dname") and then memmoves the result to the LHS of the assignment ("ddname"). The ICE occured because '"h "' is not an address expression. The following patch works. The dump also looks OK (cf. above) - though, I do not know whether it causes missed-optimization or other issues. --- a/gcc/fortran/trans-expr.c +++ b/gcc/fortran/trans-expr.c @@ -1438,9 +1438,9 @@ gfc_conv_expr_op (gfc_se * se, gfc_expr * expr) tree gfc_string_to_single_character (tree len, tree str, int kind) { - gcc_assert (POINTER_TYPE_P (TREE_TYPE (str))); - if (!INTEGER_CST_P (len) || TREE_INT_CST_HIGH (len) != 0) + if (!INTEGER_CST_P (len) || TREE_INT_CST_HIGH (len) != 0 + || !POINTER_TYPE_P (TREE_TYPE (str))) return NULL_TREE; if (TREE_INT_CST_LOW (len) == 1) @@ -3831,7 +3831,7 @@ gfc_trans_string_copy (stmtblock_t * block, tree dlength, tree dest, else dest = gfc_build_addr_expr (pvoid_type_node, dest); - if (slength) + if (slength && POINTER_TYPE_P (TREE_TYPE (src))) src = fold_convert (pvoid_type_node, src); else src = gfc_build_addr_expr (pvoid_type_node, src);