See 31610 for another example. "13.7.75 MERGE (TSOURCE, FSOURCE, MASK)" "FSOURCE shall be of the same type and type parameters as TSOURCE." NAG f95: Error: merge_char_3.f90, line 4: Unequal character lengths (2 and 3) in MERGE intrinsic Error: merge_char_3.f90, line 5: Unequal character lengths (2 and 3) in MERGE intrinsic implicit none character(len=2) :: a character(len=3) :: b print *, merge(a,b,.true.) ! { dg-error "Unequal character lengths" } print *, merge('aa','bbb',.true.) ! { dg-error "Unequal character lengths" } end First version of a patch follows. However, it does not detect the second transfer as for 'aa' expr->ts.cl->length etc. is not set, but only expr->value.character.length (cf. match_string_constant). (Note: setting cl.* in match_string_constant does not completely work: In gfortran.dg/char_length_1.f90 the warning for line 12 and 14 is then suppressed.) Index: check.c =================================================================== --- check.c (Revision 128550) +++ check.c (Arbeitskopie) @@ -1820,6 +1820,23 @@ if (same_type_check (tsource, 0, fsource, 1) == FAILURE) return FAILURE; + /* In case of characters, the string lengths need to match. */ + if (tsource->ts.type == BT_CHARACTER && tsource->ts.cl + && tsource->ts.cl->length && fsource->ts.cl && fsource->ts.cl->length + && tsource->ts.cl->length->expr_type == EXPR_CONSTANT + && fsource->ts.cl->length->expr_type == EXPR_CONSTANT + && mpz_cmp (tsource->ts.cl->length->value.integer, + fsource->ts.cl->length->value.integer) != 0) + { + gfc_error ("Unequal character lengths (%ld and %ld) in MERGE " + "intrinsic at %L", + mpz_get_si (tsource->ts.cl->length->value.integer), + mpz_get_si (fsource->ts.cl->length->value.integer), + &tsource->where); + return FAILURE; + } + + if (type_check (mask, 2, BT_LOGICAL) == FAILURE) return FAILURE; In case some one is interested in the match_string_constant change (which causes the warn regression), here it comes: Index: primary.c =================================================================== --- primary.c (Revision 128550) +++ primary.c (Arbeitskopie) @@ -946,6 +946,8 @@ got_delim: e->value.character.string = p = gfc_getmem (length + 1); e->value.character.length = length; + e->ts.cl = gfc_get_charlen (); + e->ts.cl->length = gfc_int_expr (length); gfc_current_locus = start_locus; gfc_next_char (); /* Skip delimiter */
I think the primary.c patchlet could mess up with more than diagnostics: the difference between expr->ts.cl->length etc. and expr->value.character.length is used in quite a few places in the front-end, I think. Why not having a gfc_check_same_length() helper function that would look at both expr->ts.cl->length etc. and expr->value.character.length to handle all three cases: (var,var), (parameter,parameter) and (var,parameter)?
Subject: Bug 33455 Author: burnus Date: Fri Sep 21 10:44:20 2007 New Revision: 128647 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=128647 Log: 2007-09-21 Tobias Burnus <burnus@net-b.de> PR fortran/33455 * check.c (check_same_strlen): New function. (gfc_check_merge): Use it. 2007-09-21 Tobias Burnus <burnus@net-b.de> PR fortran/33455 * gfortran.dg/merge_char_3.f90: New. Added: trunk/gcc/testsuite/gfortran.dg/merge_char_2.f90 Modified: trunk/gcc/fortran/check.c trunk/gcc/testsuite/ChangeLog
Fixed on the trunk (4.3.0).
Subject: Bug number PR33455 A patch for this bug has been added to the patch tracker. The mailing list url for the patch is http://gcc.gnu.org/ml/gcc-patches/2007-09/msg01663.html