Bug 27784 - Comparison of strings with char(0)
Summary: Comparison of strings with char(0)
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: libfortran (show other bugs)
Version: 4.2.0
: P3 normal
Target Milestone: 4.1.2
Assignee: Thomas Koenig
URL:
Keywords: patch
Depends on:
Blocks: 19292
  Show dependency treegraph
 
Reported: 2006-05-28 11:12 UTC by Thomas Koenig
Modified: 2006-06-20 06:13 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work: 4.2.0 4.1.2
Known to fail:
Last reconfirmed: 2006-05-28 14:04:28


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Thomas Koenig 2006-05-28 11:12:38 UTC
$ cat string_null_compare_1.f
      program main
      character*3 str1, str2
      call setval(str1, str2)
      if (str1 == str2) print *,'Should be unqual'
      end

      subroutine setval(str1, str2)
      character*3 str1, str2
      str1 = 'a' // CHAR(0) // 'a'
      str2 = 'a' // CHAR(0) // 'c'
      end
$ gfortran string_null_compare_1.f
$ ./a.out
 Should be unqual
$ g77 string_null_compare_1.f
$ ./a.out
$
Comment 1 Francois-Xavier Coudert 2006-05-28 15:49:01 UTC
What about simply doing:

Index: intrinsics/string_intrinsics.c
===================================================================
--- intrinsics/string_intrinsics.c      (revision 113849)
+++ intrinsics/string_intrinsics.c      (working copy)
@@ -109,7 +109,7 @@
   const char *s;
   int len;
 
-  res = strncmp (s1, s2, (len1 < len2) ? len1 : len2);
+  res = memcmp (s1, s2, (len1 < len2) ? len1 : len2);
   if (res != 0)
     return res;
 

I was told that using memcmp is safe without checking it in configury, because it is present in libiberty if not in the system.
Comment 2 Thomas Koenig 2006-05-28 16:05:36 UTC
(In reply to comment #1)
> What about simply doing:
> 
> Index: intrinsics/string_intrinsics.c
> ===================================================================
> --- intrinsics/string_intrinsics.c      (revision 113849)
> +++ intrinsics/string_intrinsics.c      (working copy)
> @@ -109,7 +109,7 @@
>    const char *s;
>    int len;
> 
> -  res = strncmp (s1, s2, (len1 < len2) ? len1 : len2);
> +  res = memcmp (s1, s2, (len1 < len2) ? len1 : len2);
>    if (res != 0)
>      return res;

Yes, this works.  I actually regtested and submitted this,
but somehow E-Mail to the fortran mailing list has been
broken for me.  Mabe the E-Mail will appear a bit later.

In the meantime, this patch is approved :-)

Thomas
Comment 3 Francois-Xavier Coudert 2006-05-28 16:28:23 UTC
(In reply to comment #2)
> In the meantime, this patch is approved :-)

No, your patch is approved! Please go ahead and commit :)
Comment 4 Francois-Xavier Coudert 2006-06-19 22:16:05 UTC
This was fixed on mainline by:

r114175 | tkoenig | 2006-05-28 22:25:15 +0200 (Sun, 28 May 2006) | 11 lines

2006-05-28  Thomas Koenig  <Thomas.Koenig@online.de>

        * intrinsics/string_intrinsics.c (compare_string):
        Use memcmp instead of strncmp to avoid tripping over
        CHAR(0) in a string.

2006-05-28  Thomas Koenig  <Thomas.Koenig@online.de>

        * gfortran.dg/string_null_compare_1.f:  New test case.
Comment 5 Francois-Xavier Coudert 2006-06-20 06:04:29 UTC
Subject: Bug 27784

Author: fxcoudert
Date: Tue Jun 20 06:04:14 2006
New Revision: 114803

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=114803
Log:
2006-06-20  Francois-Xavier Coudert  <coudert@clipper.ens.fr>

	PR fortran/27958
	* trans-expr.c (gfc_conv_substring): If the substring start is
	greater than its end, the length of the substring is zero, and
	not negative.
	(gfc_trans_string_copy): Don't generate a call to
	_gfortran_copy_string when destination length is zero.

2006-06-20  Francois-Xavier Coudert  <coudert@clipper.ens.fr>

	PR libfortran/27895
	* resolve.c (compute_last_value_for_triplet): New function.
	(check_dimension): Correctly handle zero-sized array sections.
	Add checking on last element of array sections.

2006-06-20  Francois-Xavier Coudert  <coudert@clipper.ens.fr>

	* trans.c (gfc_msg_bounds, gfc_msg_fault, gfc_msg_wrong_return):
	Add strings for common runtime error messages.
	(gfc_trans_runtime_check): Add a locus argument, use a string
	and not a string tree for the message.
	* trans.h (gfc_trans_runtime_check): Change prototype accordingly.
	(gfc_msg_bounds, gfc_msg_fault, gfc_msg_wrong_return): Add proto.
	* trans-const.c (gfc_strconst_bounds, gfc_strconst_fault,
	gfc_strconst_wrong_return, gfc_strconst_current_filename): Remove.
	(gfc_init_constants): Likewise.
	* trans-const.h: Likewise.
	* trans-decl.c (gfc_build_builtin_function_decls): Call to
	_gfortran_runtime_error has only one argument, the message string.
	* trans-array.h (gfc_conv_array_ref): Add a symbol argument and a
	locus.
	* trans-array.c (gfc_trans_array_bound_check): Build precise
	error messages.
	(gfc_conv_array_ref): Use the new symbol argument and the locus
	to build more precise error messages.
	(gfc_conv_ss_startstride): More precise error messages.
	* trans-expr.c (gfc_conv_variable): Give symbol reference and
	locus to gfc_conv_array_ref.
	(gfc_conv_function_call): Use the new prototype for
	gfc_trans_runtime_check.
	* trans-stmt.c (gfc_trans_goto): Build more precise error message.
	* trans-io.c (set_string): Likewise.
	* trans-intrinsic.c (gfc_conv_intrinsic_bound): Use new prototype
	for gfc_trans_runtime_check.

2006-06-20  Thomas Koenig  <Thomas.Koenig@online.de>

	PR fortran/27715
	* arith.c:  Cast the characters from the strings to unsigned
	char to avoid values less than 0 for extended ASCII.

2006-06-20  Thomas Koenig  <Thomas.Koenig@online.de>

	PR libfortran/27784
	* intrinsics/string_intrinsics.c (compare_string):
	Use memcmp instead of strncmp to avoid tripping over
	CHAR(0) in a string.

2006-06-20  Francois-Xavier Coudert  <coudert@clipper.ens.fr>

	PR fortran/27958
	* gcc/testsuite/gfortran.dg/substr_2.f: New test.

2006-06-20  Francois-Xavier Coudert  <coudert@clipper.ens.fr>

	PR libfortran/27895
	* gfortran.dg/bounds_check_3.f90: New test.

2006-06-20  Thomas Koenig  <Thomas.Koenig@online.de>

	PR fortran/27715
	* gfortran.dg/extended_char_comparison_1.f:  New test.

2006-06-20  Thomas Koenig  <Thomas.Koenig@online.de>

	PR fortran/27784
	* gfortran.dg/string_null_compare_1.f:  New test case.

Added:
    branches/gcc-4_1-branch/gcc/testsuite/gfortran.dg/bounds_check_3.f90
      - copied unchanged from r114414, trunk/gcc/testsuite/gfortran.dg/bounds_check_3.f90
    branches/gcc-4_1-branch/gcc/testsuite/gfortran.dg/extended_char_comparison_1.f
      - copied unchanged from r114317, trunk/gcc/testsuite/gfortran.dg/extended_char_comparison_1.f
    branches/gcc-4_1-branch/gcc/testsuite/gfortran.dg/string_null_compare_1.f
      - copied unchanged from r114175, trunk/gcc/testsuite/gfortran.dg/string_null_compare_1.f
    branches/gcc-4_1-branch/gcc/testsuite/gfortran.dg/substr_2.f
      - copied unchanged from r114496, trunk/gcc/testsuite/gfortran.dg/substr_2.f
Modified:
    branches/gcc-4_1-branch/gcc/fortran/ChangeLog
    branches/gcc-4_1-branch/gcc/fortran/arith.c
    branches/gcc-4_1-branch/gcc/fortran/resolve.c
    branches/gcc-4_1-branch/gcc/fortran/trans-array.c
    branches/gcc-4_1-branch/gcc/fortran/trans-array.h
    branches/gcc-4_1-branch/gcc/fortran/trans-const.c
    branches/gcc-4_1-branch/gcc/fortran/trans-const.h
    branches/gcc-4_1-branch/gcc/fortran/trans-decl.c
    branches/gcc-4_1-branch/gcc/fortran/trans-expr.c
    branches/gcc-4_1-branch/gcc/fortran/trans-intrinsic.c
    branches/gcc-4_1-branch/gcc/fortran/trans-io.c
    branches/gcc-4_1-branch/gcc/fortran/trans-stmt.c
    branches/gcc-4_1-branch/gcc/fortran/trans.c
    branches/gcc-4_1-branch/gcc/fortran/trans.h
    branches/gcc-4_1-branch/gcc/testsuite/ChangeLog
    branches/gcc-4_1-branch/libgfortran/ChangeLog
    branches/gcc-4_1-branch/libgfortran/intrinsics/string_intrinsics.c

Comment 6 Francois-Xavier Coudert 2006-06-20 06:13:23 UTC
Fixed.