This is the mail archive of the
fortran@gcc.gnu.org
mailing list for the GNU Fortran project.
[patch,fortran] Fix keyword check for specifiers (PR29452)
- From: Tobias Burnus <burnus at net-b dot de>
- To: "'fortran at gcc dot gnu dot org'" <fortran at gcc dot gnu dot org>, gcc-patches <gcc-patches at gcc dot gnu dot org>
- Date: Thu, 26 Oct 2006 10:20:15 +0200
- Subject: [patch,fortran] Fix keyword check for specifiers (PR29452)
:ADDPATCH fortran:
Hello,
this patch fixes some problems with the string comparisons for the
argument checks:
- In libgfortran, the "YES"/"NO" etc. checks where only checking whether
the first (length of fortran string) characters match. That way (Fortran
string) "N" matched (C string) "NO" etc.
- In the write/read check section of io.c, the advance argument was
compared against "YE" and "NO", thus "NOT", "YET","Yessica", etc. also
matches. As we have C strings, I replaced the str-n-casecmp( . , . , 2)
by strcasecmp.
I didn't use compare_to_allowed_values as the "not_no" is also used for
other checks (EOR and SIZE). When the missing 7 specifiers with keywords
are added, one can consider changing also this test to use
compare_to_allowed_values.
Tobias
2006-10-26 Tobias Burnus <burnus@net-b.de>
PR fortran/29452
* io.c (check_io_constraints): Fix keyword string comparison.
2006-10-26 Tobias Burnus <burnus@net-b.de>
PR fortran/29452
* runtime/string.c (compare0): Check whether string lengths match.
2006-10-26 Tobias Burnus <burnus@net-b.de>
PR fortran/29452
* gfortran.dg/write_check.f90: Check run-time keyword checking.
* gfortran.dg/write_check2.f90: Check compile-time keyword checking.
Index: gcc/fortran/io.c
===================================================================
--- gcc/fortran/io.c (Revision 118060)
+++ gcc/fortran/io.c (Arbeitskopie)
@@ -2697,8 +2701,8 @@
if (expr->expr_type == EXPR_CONSTANT && expr->ts.type == BT_CHARACTER)
{
const char * advance = expr->value.character.string;
- not_no = strncasecmp (advance, "no", 2) != 0;
- not_yes = strncasecmp (advance, "yes", 2) != 0;
+ not_no = strcasecmp (advance, "no") != 0;
+ not_yes = strcasecmp (advance, "yes") != 0;
}
else
{
Index: libgfortran/runtime/string.c
===================================================================
--- libgfortran/runtime/string.c (Revision 118060)
+++ libgfortran/runtime/string.c (Arbeitskopie)
@@ -44,6 +44,7 @@
/* Strip trailing blanks from the Fortran string. */
len = fstrlen (s1, s1_len);
+ if(len != strlen(s2)) return 0; /* don't match */
return strncasecmp (s1, s2, len) == 0;
}
--- /dev/null 2006-10-15 18:34:35.000000000 +0200
+++ gcc/testsuite/gfortran.dg/write_check.f90 2006-10-26 09:33:23.000000000 +0200
@@ -0,0 +1,13 @@
+! { dg-do run }
+program test
+ implicit none
+ character(len=5) :: str
+ str = 'no'
+ write(*,'(a)',advance=str) 'Foo'
+ str = 'yes'
+ write(*,'(a)',advance=str) 'Foo'
+ str = 'NOT'
+ write(*,'(a)',advance=str) 'Foo'
+end program test
+! { dg-output "At line 10 of file.*" }
+! { dg-output "Fortran runtime error: Bad ADVANCE parameter in data transfer statement" }
--- /dev/null 2006-10-15 18:34:35.000000000 +0200
+++ gcc/testsuite/gfortran.dg/write_check2.f90 2006-10-17 00:45:40.000000000 +0200
@@ -0,0 +1,8 @@
+! { dg-do compile }
+ character(len=20) :: str
+ write(13,'(a)',advance='yes') 'Hello:'
+ write(13,'(a)',advance='no') 'Hello:'
+ write(13,'(a)',advance='y') 'Hello:' ! { dg-error "ADVANCE=specifier at (1) must have value = YES or NO."}
+ write(13,'(a)',advance='yet') 'Hello:' ! { dg-error "ADVANCE=specifier at (1) must have value = YES or NO."}
+ write(13,'(a)',advance='yess') 'Hello:' ! { dg-error "ADVANCE=specifier at (1) must have value = YES or NO."}
+ end