Re: [patch, fortran] Add modular exponentiation for unsigned

2025-02-03 Thread Thomas Koenig

Hello world,

with the following patch to the failing test case

diff --git a/gcc/testsuite/gfortran.dg/unsigned_15.f90 
b/gcc/testsuite/gfortran.dg/unsigned_15.f90

index da4ccd2dc17..80a7a54e380 100644
--- a/gcc/testsuite/gfortran.dg/unsigned_15.f90
+++ b/gcc/testsuite/gfortran.dg/unsigned_15.f90
@@ -6,8 +6,8 @@ program main
   unsigned :: u
   print *,1 + 2u   ! { dg-error "Operands of binary numeric operator" }
   print *,2u + 1   ! { dg-error "Operands of binary numeric operator" }
-  print *,2u ** 1  ! { dg-error "Exponentiation not valid" }
-  print *,2u ** 1u ! { dg-error "Exponentiation not valid" }
+  print *,2u ** 1  ! { dg-error "Operands of binary numeric operator" }
+  print *,2u ** 1u
   print *,1u < 2   ! { dg-error "Inconsistent types" }
   print *,int(1u) < 2
 end program main

the patch posted to

https://gcc.gnu.org/pipermail/fortran/2025-February/061670.html

and

https://gcc.gnu.org/pipermail/gcc-patches/2025-February/674931.html

passes (I don't want to re-submit the whole thing).

OK for trunk?

Best regards

Thomas



Re: How to do a seek (nonadvancing read) on a stream file?

2025-02-03 Thread Jerry D

On 2/3/25 12:10 PM, Andi McClure wrote:
(This is an attempt to reply to a Mon Feb 3 19:09:38 GMT 2025 message by 
Steve Kargl.)


 > I believe that you are misreading C1223.  The file is
 > opened with form='unformatted'.

Hm, okay. I guess it comes down to whether you "diagram" the sentence in 
the spec as "An ADVANCE= specifier shall appear only in a formatted 
(sequential or stream) data transfer statement"  or "An ADVANCE= 
specifier shall appear only in a (formatted sequential) or (stream data 
transfer) statement". If you interpret it the first way the gfortran 
behavior is correct (although the error message could be improved…), if 
you interpret it the second way gfortran is incorrect.


 > PS: You're looking for the INQUIRE statement.

In the context of the program I was trying to write, INQUIRE can be used 
to get the byte length of the file. That is not something I was trying 
to do. The data was structured, and needed to be parsed to determine the 
allocation size. In other words INQUIRE is the equivalent of C ftell() 
and I am looking for the equivalent of C fseek(). (Which the standard 
appears to only offer through nonadvancing reads… which gfortran appears 
to disallow for an unformatted stream file. Unless you do the "silly" 
thing I eventually did, which is to bundle your seek together with the 
next advancing read.)


Thanks for the information.



This mailing list is intended for developers and contributors.

I suggest you post your Fortran questions to this group which is a lot 
of users.


https://fortran-lang.discourse.group/

Regards,

Jerry


Re: How to do a seek (nonadvancing read) on a stream file?

2025-02-03 Thread Steve Kargl
On Mon, Feb 03, 2025 at 01:34:09PM -0500, Andi McClure wrote:
> 
> open(10,file=path,access='stream',form='unformatted',action='read',iostat=file_error)

You opened the file with form='unformatted'.

> READ (iu,"()", ADVANCE='NO', POS=file_pos) ! iu is file unit

You then try to use a format statement.

> At line 88 of file src/puzzle.f90 (unit = 10, file = 'data/sample-2.18.txt')
> Fortran runtime error: Format present for UNFORMATTED data transfer

You get the obvious error.

>88 | read(10, advance='no', pos=1)
>   | 1
> Error: the ADVANCE= specifier at (1) must appear with an explicit format
> expression

(snip)

> > C1223 (R1213) An ADVANCE= specifier shall appear only in a
> > formatted sequential or stream data transfer statement with
> > explicit format specification (13.2) whose io-control-spec-list
> > does not contain an internal-file-variable as the io-unit.

I believe that you are misreading C1223.  The file is 
opened with form='unformatted'.  C1223 should be read as

C1223 An ADVANCE= specifier shall appear only in a 
formatted RED or BLUE data transfer statement ...

with RED and BLUE an obvious substitution for clarify the parsing.

Of course, I could be wrong.

PS: You're looking for the INQUIRE statement.

integer fd, n
character(len=:), allocatable :: string
inquire(file=..., size=n)
allocate(character(len=n) :: string)
open(fd,file=..., access='stream',status='old')
read(fd) string
close(fd)

-- 
Steve


Re: [PING, PATCH] fortran: fix -MT/-MQ adding additional target [PR47485]

2025-02-03 Thread Vincent Vanlaer

Hi all,

Gentle ping for the patch below: 
https://gcc.gnu.org/pipermail/fortran/2024-December/061467.html


Best wishes,
Vincent

On 30/12/2024 00:19, Vincent Vanlaer wrote:

The -MT and -MQ options should replace the default target in the
generated dependency file. deps_add_target needs to be called before
cpp_read_main_file, otherwise the original object name is added.

gcc/fortran/
PR fortran/47485
* cpp.cc: fix -MT/-MQ adding additional target instead of
  replacing the default

gcc/testsuite/
PR fortran/47485
* gfortran.dg/dependency_generation_1.f90: New test

Signed-off-by: Vincent Vanlaer 
---
  gcc/fortran/cpp.cc | 18 --
  .../gfortran.dg/dependency_generation_1.f90| 15 +++
  2 files changed, 27 insertions(+), 6 deletions(-)
  create mode 100644 gcc/testsuite/gfortran.dg/dependency_generation_1.f90

diff --git a/gcc/fortran/cpp.cc b/gcc/fortran/cpp.cc
index 7c5f00cfd69..3b93d17b90f 100644
--- a/gcc/fortran/cpp.cc
+++ b/gcc/fortran/cpp.cc
@@ -96,6 +96,8 @@ struct gfc_cpp_option_data
int deps_skip_system; /* -MM */
const char *deps_filename;/* -M[M]D */
const char *deps_filename_user;   /* -MF  */
+  const char *deps_target_filename; /* -MT / -MQ  */
+  bool quote_deps_target_filename;  /* -MQ */
int deps_missing_are_generated;   /* -MG */
int deps_phony;   /* -MP */
int warn_date_time;   /* -Wdate-time */
@@ -287,6 +289,8 @@ gfc_cpp_init_options (unsigned int decoded_options_count,
gfc_cpp_option.deps_missing_are_generated = 0;
gfc_cpp_option.deps_filename = NULL;
gfc_cpp_option.deps_filename_user = NULL;
+  gfc_cpp_option.deps_target_filename = NULL;
+  gfc_cpp_option.quote_deps_target_filename = false;
  
gfc_cpp_option.multilib = NULL;

gfc_cpp_option.prefix = NULL;
@@ -439,9 +443,8 @@ gfc_cpp_handle_option (size_t scode, const char *arg, int 
value ATTRIBUTE_UNUSED
  
  case OPT_MQ:

  case OPT_MT:
-  gfc_cpp_option.deferred_opt[gfc_cpp_option.deferred_opt_count].code = 
code;
-  gfc_cpp_option.deferred_opt[gfc_cpp_option.deferred_opt_count].arg = arg;
-  gfc_cpp_option.deferred_opt_count++;
+  gfc_cpp_option.quote_deps_target_filename = (code == OPT_MQ);
+  gfc_cpp_option.deps_target_filename = arg;
break;
  
  case OPT_P:

@@ -593,6 +596,12 @@ gfc_cpp_init_0 (void)
  }
  
gcc_assert(cpp_in);

+
+  if (gfc_cpp_option.deps_target_filename)
+if (mkdeps *deps = cpp_get_deps (cpp_in))
+  deps_add_target (deps, gfc_cpp_option.deps_target_filename,
+  gfc_cpp_option.quote_deps_target_filename);
+
if (!cpp_read_main_file (cpp_in, gfc_source_file))
  errorcount++;
  }
@@ -635,9 +644,6 @@ gfc_cpp_init (void)
  else
cpp_assert (cpp_in, opt->arg);
}
-  else if (opt->code == OPT_MT || opt->code == OPT_MQ)
-   if (mkdeps *deps = cpp_get_deps (cpp_in))
- deps_add_target (deps, opt->arg, opt->code == OPT_MQ);
  }
  
/* Pre-defined macros for non-required INTEGER kind types.  */

diff --git a/gcc/testsuite/gfortran.dg/dependency_generation_1.f90 
b/gcc/testsuite/gfortran.dg/dependency_generation_1.f90
new file mode 100644
index 000..d42a257f83a
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dependency_generation_1.f90
@@ -0,0 +1,15 @@
+! This test case ensures that the -MT flag is correctly replacing the object 
name in the dependency file.
+! See PR 47485
+!
+! Contributed by Vincent Vanlaer 
+!
+! { dg-do preprocess }
+! { dg-additional-options "-cpp" }
+! { dg-additional-options "-M" }
+! { dg-additional-options "-MF deps" }
+! { dg-additional-options "-MT obj.o" }
+
+module test
+end module
+
+! { dg-final { scan-file "deps" "obj.o:.*" } }




Re: [patch, fortran] Add modular exponentiation for unsigned

2025-02-03 Thread Jerry D

On 2/3/25 11:55 AM, Thomas Koenig wrote:

Hello world,

with the following patch to the failing test case

diff --git a/gcc/testsuite/gfortran.dg/unsigned_15.f90 b/gcc/testsuite/ 
gfortran.dg/unsigned_15.f90

index da4ccd2dc17..80a7a54e380 100644
--- a/gcc/testsuite/gfortran.dg/unsigned_15.f90
+++ b/gcc/testsuite/gfortran.dg/unsigned_15.f90
@@ -6,8 +6,8 @@ program main
    unsigned :: u
    print *,1 + 2u   ! { dg-error "Operands of binary numeric operator" }
    print *,2u + 1   ! { dg-error "Operands of binary numeric operator" }
-  print *,2u ** 1  ! { dg-error "Exponentiation not valid" }
-  print *,2u ** 1u ! { dg-error "Exponentiation not valid" }
+  print *,2u ** 1  ! { dg-error "Operands of binary numeric operator" }
+  print *,2u ** 1u
    print *,1u < 2   ! { dg-error "Inconsistent types" }
    print *,int(1u) < 2
  end program main

the patch posted to

https://gcc.gnu.org/pipermail/fortran/2025-February/061670.html

and

https://gcc.gnu.org/pipermail/gcc-patches/2025-February/674931.html

passes (I don't want to re-submit the whole thing).

OK for trunk?

Best regards

 Thomas



Yes, please proceed.

Jerry


Re: [PATCH] Fortran: different character lengths in array constructor [PR93289]

2025-02-03 Thread Harald Anlauf

Am 03.02.25 um 19:31 schrieb Jerry D:

On 2/3/25 2:49 AM, Richard Sandiford wrote:

Steve Kargl  writes:

On Sat, Feb 01, 2025 at 09:49:17PM +0100, Harald Anlauf wrote:

Am 01.02.25 um 21:03 schrieb Steve Kargl:

On Sat, Feb 01, 2025 at 07:25:51PM +0100, Harald Anlauf wrote:


the attached patch downgrades different constant character lengths
in an
array constructor from a GNU to a legacy extension, so that users
get a
warning with -std=gnu.  We continue to generate an error when
standard
conformance is requested.

Regtested on x86_64-pc-linux-gnu (found one testcase where this
triggered... :)

OK for mainline?



My vote is 'no'.

This is either a GNU extension or an error.  It is certainly
not a legacy issue as array constructors simple cannot appear
old moldy *legacy* codes.


legacy /= moldy.

My intention is to downgrade existing, potentially dangerous
GNU extensions (like this one) carefully to "legacy", but not
with an axe.


I would be in favor of making it a hard error.  If you believe
gfortan must be able to compile invalid source, then add an option
such as -fallow-invalid-scalar-character-entities-in-array-
constructor.


I don't see why we shall scare users by making code that is currently
accepted silently, because it is a GNU extension, suddenly to a hard
error.

So why must we be so tough?



Because -std=legacy allows a whole bunch of garbage.

Instead of fixing broken code, a user will slap -std=legacy
in a Makefile and move on.  Then years from now, you'll see
-std=legacy in a whole bunch of Makefiles whether it is needed
or not.  See -maligned-double and -fallow-argument-mismatch as
poster children.


I agree that this is what will happen.  But for people running
benchmarks,
it's kind-of (kind-of) a feature.  Benchmarks tend to include relatively
old code by the time that they're released, and benchmarks continue to be
relevant (or at least widely tested) after they're out of maintenance.

So it has been really useful to have -std=legacy accept old, dangerous
code,
since it means that we can continue to test old benchmarks with newer
compilers.  Improving the benchmark source to avoid the dangerous
constructs
would invalidate the test and make it harder to compare with historical
results.


Again, just my $0.02.


Same here, just wanted to raise the benchmark use case.

Thanks,
Richard


I think we have had good discussion and for sake of the good of the
order I recommend we push this for now.  The work has been done.

Regards,

Jerry



Thanks, Jerry!

Pushed: r15-7336-gf3a41e6cb5d70f



Re: [PING, PATCH] fortran: fix -MT/-MQ adding additional target [PR47485]

2025-02-03 Thread Jerry D

On 2/3/25 2:14 PM, Vincent Vanlaer wrote:

Hi all,

Gentle ping for the patch below: https://gcc.gnu.org/pipermail/ 
fortran/2024-December/061467.html


Best wishes,
Vincent

On 30/12/2024 00:19, Vincent Vanlaer wrote:

The -MT and -MQ options should replace the default target in the
generated dependency file. deps_add_target needs to be called before
cpp_read_main_file, otherwise the original object name is added.

gcc/fortran/
PR fortran/47485
* cpp.cc: fix -MT/-MQ adding additional target instead of
  replacing the default

gcc/testsuite/
PR fortran/47485
* gfortran.dg/dependency_generation_1.f90: New test

Signed-off-by: Vincent Vanlaer 
---
  gcc/fortran/cpp.cc | 18 --
  .../gfortran.dg/dependency_generation_1.f90    | 15 +++
  2 files changed, 27 insertions(+), 6 deletions(-)
  create mode 100644 gcc/testsuite/gfortran.dg/ 
dependency_generation_1.f90


diff --git a/gcc/fortran/cpp.cc b/gcc/fortran/cpp.cc
index 7c5f00cfd69..3b93d17b90f 100644
--- a/gcc/fortran/cpp.cc
+++ b/gcc/fortran/cpp.cc
@@ -96,6 +96,8 @@ struct gfc_cpp_option_data
    int deps_skip_system; /* -MM */
    const char *deps_filename;    /* -M[M]D */
    const char *deps_filename_user;   /* -MF  */
+  const char *deps_target_filename; /* -MT / -MQ  */
+  bool quote_deps_target_filename;  /* -MQ */
    int deps_missing_are_generated;   /* -MG */
    int deps_phony;   /* -MP */
    int warn_date_time;   /* -Wdate-time */
@@ -287,6 +289,8 @@ gfc_cpp_init_options (unsigned int 
decoded_options_count,

    gfc_cpp_option.deps_missing_are_generated = 0;
    gfc_cpp_option.deps_filename = NULL;
    gfc_cpp_option.deps_filename_user = NULL;
+  gfc_cpp_option.deps_target_filename = NULL;
+  gfc_cpp_option.quote_deps_target_filename = false;
    gfc_cpp_option.multilib = NULL;
    gfc_cpp_option.prefix = NULL;
@@ -439,9 +443,8 @@ gfc_cpp_handle_option (size_t scode, const char 
*arg, int value ATTRIBUTE_UNUSED

  case OPT_MQ:
  case OPT_MT:
-  
gfc_cpp_option.deferred_opt[gfc_cpp_option.deferred_opt_count].code = 
code;
-  
gfc_cpp_option.deferred_opt[gfc_cpp_option.deferred_opt_count].arg = arg;

-  gfc_cpp_option.deferred_opt_count++;
+  gfc_cpp_option.quote_deps_target_filename = (code == OPT_MQ);
+  gfc_cpp_option.deps_target_filename = arg;
    break;
  case OPT_P:
@@ -593,6 +596,12 @@ gfc_cpp_init_0 (void)
  }
    gcc_assert(cpp_in);
+
+  if (gfc_cpp_option.deps_target_filename)
+    if (mkdeps *deps = cpp_get_deps (cpp_in))
+  deps_add_target (deps, gfc_cpp_option.deps_target_filename,
+   gfc_cpp_option.quote_deps_target_filename);
+
    if (!cpp_read_main_file (cpp_in, gfc_source_file))
  errorcount++;
  }
@@ -635,9 +644,6 @@ gfc_cpp_init (void)
    else
  cpp_assert (cpp_in, opt->arg);
  }
-  else if (opt->code == OPT_MT || opt->code == OPT_MQ)
-    if (mkdeps *deps = cpp_get_deps (cpp_in))
-  deps_add_target (deps, opt->arg, opt->code == OPT_MQ);
  }
    /* Pre-defined macros for non-required INTEGER kind types.  */
diff --git a/gcc/testsuite/gfortran.dg/dependency_generation_1.f90 b/ 
gcc/testsuite/gfortran.dg/dependency_generation_1.f90

new file mode 100644
index 000..d42a257f83a
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dependency_generation_1.f90
@@ -0,0 +1,15 @@
+! This test case ensures that the -MT flag is correctly replacing the 
object name in the dependency file.

+! See PR 47485
+!
+! Contributed by Vincent Vanlaer 
+!
+! { dg-do preprocess }
+! { dg-additional-options "-cpp" }
+! { dg-additional-options "-M" }
+! { dg-additional-options "-MF deps" }
+! { dg-additional-options "-MT obj.o" }
+
+module test
+end module
+
+! { dg-final { scan-file "deps" "obj.o:.*" } }




Do you have commit rights to gcc? I did not catch your original post.

Jerry


Re: [PING, PATCH] fortran: fix -MT/-MQ adding additional target [PR47485]

2025-02-03 Thread Vincent Vanlaer





On 4/02/2025 01:42, Jerry D wrote:

On 2/3/25 2:14 PM, Vincent Vanlaer wrote:

Hi all,

Gentle ping for the patch below: https://gcc.gnu.org/pipermail/ 
fortran/2024-December/061467.html


Best wishes,
Vincent

On 30/12/2024 00:19, Vincent Vanlaer wrote:

The -MT and -MQ options should replace the default target in the
generated dependency file. deps_add_target needs to be called before
cpp_read_main_file, otherwise the original object name is added.

gcc/fortran/
PR fortran/47485
* cpp.cc: fix -MT/-MQ adding additional target instead of
  replacing the default

gcc/testsuite/
PR fortran/47485
* gfortran.dg/dependency_generation_1.f90: New test

Signed-off-by: Vincent Vanlaer 
---
  gcc/fortran/cpp.cc | 18 
--

  .../gfortran.dg/dependency_generation_1.f90    | 15 +++
  2 files changed, 27 insertions(+), 6 deletions(-)
  create mode 100644 gcc/testsuite/gfortran.dg/ 
dependency_generation_1.f90


diff --git a/gcc/fortran/cpp.cc b/gcc/fortran/cpp.cc
index 7c5f00cfd69..3b93d17b90f 100644
--- a/gcc/fortran/cpp.cc
+++ b/gcc/fortran/cpp.cc
@@ -96,6 +96,8 @@ struct gfc_cpp_option_data
    int deps_skip_system; /* -MM */
    const char *deps_filename;    /* -M[M]D */
    const char *deps_filename_user;   /* -MF  */
+  const char *deps_target_filename; /* -MT / -MQ  */
+  bool quote_deps_target_filename;  /* -MQ */
    int deps_missing_are_generated;   /* -MG */
    int deps_phony;   /* -MP */
    int warn_date_time;   /* -Wdate-time */
@@ -287,6 +289,8 @@ gfc_cpp_init_options (unsigned int 
decoded_options_count,

    gfc_cpp_option.deps_missing_are_generated = 0;
    gfc_cpp_option.deps_filename = NULL;
    gfc_cpp_option.deps_filename_user = NULL;
+  gfc_cpp_option.deps_target_filename = NULL;
+  gfc_cpp_option.quote_deps_target_filename = false;
    gfc_cpp_option.multilib = NULL;
    gfc_cpp_option.prefix = NULL;
@@ -439,9 +443,8 @@ gfc_cpp_handle_option (size_t scode, const char 
*arg, int value ATTRIBUTE_UNUSED

  case OPT_MQ:
  case OPT_MT:
- 
gfc_cpp_option.deferred_opt[gfc_cpp_option.deferred_opt_count].code 
= code;
- gfc_cpp_option.deferred_opt[gfc_cpp_option.deferred_opt_count].arg 
= arg;

-  gfc_cpp_option.deferred_opt_count++;
+  gfc_cpp_option.quote_deps_target_filename = (code == OPT_MQ);
+  gfc_cpp_option.deps_target_filename = arg;
    break;
  case OPT_P:
@@ -593,6 +596,12 @@ gfc_cpp_init_0 (void)
  }
    gcc_assert(cpp_in);
+
+  if (gfc_cpp_option.deps_target_filename)
+    if (mkdeps *deps = cpp_get_deps (cpp_in))
+  deps_add_target (deps, gfc_cpp_option.deps_target_filename,
+   gfc_cpp_option.quote_deps_target_filename);
+
    if (!cpp_read_main_file (cpp_in, gfc_source_file))
  errorcount++;
  }
@@ -635,9 +644,6 @@ gfc_cpp_init (void)
    else
  cpp_assert (cpp_in, opt->arg);
  }
-  else if (opt->code == OPT_MT || opt->code == OPT_MQ)
-    if (mkdeps *deps = cpp_get_deps (cpp_in))
-  deps_add_target (deps, opt->arg, opt->code == OPT_MQ);
  }
    /* Pre-defined macros for non-required INTEGER kind types.  */
diff --git a/gcc/testsuite/gfortran.dg/dependency_generation_1.f90 
b/ gcc/testsuite/gfortran.dg/dependency_generation_1.f90

new file mode 100644
index 000..d42a257f83a
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dependency_generation_1.f90
@@ -0,0 +1,15 @@
+! This test case ensures that the -MT flag is correctly replacing 
the object name in the dependency file.

+! See PR 47485
+!
+! Contributed by Vincent Vanlaer 
+!
+! { dg-do preprocess }
+! { dg-additional-options "-cpp" }
+! { dg-additional-options "-M" }
+! { dg-additional-options "-MF deps" }
+! { dg-additional-options "-MT obj.o" }
+
+module test
+end module
+
+! { dg-final { scan-file "deps" "obj.o:.*" } }




Do you have commit rights to gcc? I did not catch your original post.

Jerry


I do not, this is my first time contributing to GCC.

Vincent


Re: How to do a seek (nonadvancing read) on a stream file?

2025-02-03 Thread Andi McClure
(This is an attempt to reply to a Mon Feb 3 19:09:38 GMT 2025 message by
Steve Kargl.)

> I believe that you are misreading C1223.  The file is
> opened with form='unformatted'.

Hm, okay. I guess it comes down to whether you "diagram" the sentence in
the spec as "An ADVANCE= specifier shall appear only in a formatted
(sequential or stream) data transfer statement"  or "An ADVANCE= specifier
shall appear only in a (formatted sequential) or (stream data transfer)
statement". If you interpret it the first way the gfortran behavior is
correct (although the error message could be improved…), if you interpret
it the second way gfortran is incorrect.

> PS: You're looking for the INQUIRE statement.

In the context of the program I was trying to write, INQUIRE can be used to
get the byte length of the file. That is not something I was trying to do.
The data was structured, and needed to be parsed to determine the
allocation size. In other words INQUIRE is the equivalent of C ftell() and
I am looking for the equivalent of C fseek(). (Which the standard appears
to only offer through nonadvancing reads… which gfortran appears to
disallow for an unformatted stream file. Unless you do the "silly" thing I
eventually did, which is to bundle your seek together with the next
advancing read.)

Thanks for the information.

On Mon, Feb 3, 2025 at 1:34 PM Andi McClure 
wrote:

> Last week, as an exercise in learning FORTRAN, I did a programming puzzle
> ( https://adventofcode.com/2024/day/4 ) with gfortran. I targeted the
> 2023 standard (*not* GNU). I saw two oddities. The first I posted about in
> this mailing list already (and it turns out there is a relevant bugzilla
> bug). The other I *think* is a bug (and I am not finding an existing
> bugzilla bug on my own), but I am less sure, so wanted to check here first
> before filing.
>
> For my solution, I needed to read in a file in stream mode, character by
> character(1). I needed to do this twice, once to find out what size array
> to load the data into and once to load the data into my newly-allocated
> array. It initially appeared stream mode would allow me to do this without
> closing and reopening the file, by "seeking" back to the beginning of the
> file using the pos= argument to READ. But when I tried to do this,
> something odd happened.
>
> Details: I open the file with
>
> ```
>
> open(10,file=path,access='stream',form='unformatted',action='read',iostat=file_error)
> ```
>
> This works; scanning to determine the input size works. Now I need to
> seek. I find this old stackoverflow answer:
> https://stackoverflow.com/a/11785795
>
> Claiming that the following code works (and implying they tested it in "
> ifort"):
>
> ```
> READ (iu,"()", ADVANCE='NO', POS=file_pos) ! iu is file unit
> ```
>
> I created a test program implementing this:
>
>
> https://github.com/mcclure/aoc2024/blob/38875a77fd48d8208ebcadfb3ec9c53fb722ef8b/04-01-wordsearch/src/puzzle.f90#L4
>
> And using a test input such as:
>
>
> https://github.com/mcclure/aoc2024/blob/38875a77fd48d8208ebcadfb3ec9c53fb722ef8b/04-01-wordsearch/data/sample-2.18.txt
>
> I can run it with `gfortran src/puzzle.f90 -std=f2023 -o program &&
> ./program data/sample-2.18.txt`. When I do this, I get a failure:
>
> ```
> At line 88 of file src/puzzle.f90 (unit = 10, file =
> 'data/sample-2.18.txt')
> Fortran runtime error: Format present for UNFORMATTED data transfer
> ```
>
> It appears it does not like the "()" format. However, imagine I edit line
> 88 to change `read(10, "()", advance='no', pos=1)` to `read(10,
> advance='no', pos=1)`, removing the format. Now I get a different error:
>
> ```
> ./program data/sample-2.18.txt
> src/puzzle.f90:88:21:
>
>88 | read(10, advance='no', pos=1)
>   | 1
> Error: the ADVANCE= specifier at (1) must appear with an explicit format
> expression
> ```
>
> So if I have a (null) format specifier the error message tells me to
> remove the format expression, and if I remove the format specifier the
> error message tells me to add a format expression. There appears to be *no
> way* of using advance='no' that will not cause gfortran to emit an error;
> even putting in a (spurious/useless) read, such as with `read(10, "(a)",
> advance='no', pos=1) char_in`, produces "Fortran runtime error: Format
> present for UNFORMATTED data transfer".
>
> I do not have a specific need for this to be fixed; I eventually got my
> program to work via a workaround I would consider "silly" ( see line 102:
> https://github.com/mcclure/aoc2024/blob/ca77f141f33ab494dc1bb43f3d6f13e775a36303/04-01-wordsearch/src/puzzle.f90#L102
> ). However it seems like there is a bug here, for three reasons: because
> having some method of seeking the file without simultaneously doing a read
> is fundamentally desirable; because the error messages seem to give
> misleading directions; and because I *think* this is a standard
> nonconformance.
>
> If I look at the current standard ( 2023 draft documen

Re: [PATCH] Fortran: different character lengths in array constructor [PR93289]

2025-02-03 Thread Richard Sandiford
Steve Kargl  writes:
> On Sat, Feb 01, 2025 at 09:49:17PM +0100, Harald Anlauf wrote:
>> Am 01.02.25 um 21:03 schrieb Steve Kargl:
>> > On Sat, Feb 01, 2025 at 07:25:51PM +0100, Harald Anlauf wrote:
>> > > 
>> > > the attached patch downgrades different constant character lengths in an
>> > > array constructor from a GNU to a legacy extension, so that users get a
>> > > warning with -std=gnu.  We continue to generate an error when standard
>> > > conformance is requested.
>> > > 
>> > > Regtested on x86_64-pc-linux-gnu (found one testcase where this
>> > > triggered... :)
>> > > 
>> > > OK for mainline?
>> > > 
>> > 
>> > My vote is 'no'.
>> > 
>> > This is either a GNU extension or an error.  It is certainly
>> > not a legacy issue as array constructors simple cannot appear
>> > old moldy *legacy* codes.
>> 
>> legacy /= moldy.
>> 
>> My intention is to downgrade existing, potentially dangerous
>> GNU extensions (like this one) carefully to "legacy", but not
>> with an axe.
>> 
>> > I would be in favor of making it a hard error.  If you believe
>> > gfortan must be able to compile invalid source, then add an option
>> > such as -fallow-invalid-scalar-character-entities-in-array-constructor.
>> 
>> I don't see why we shall scare users by making code that is currently
>> accepted silently, because it is a GNU extension, suddenly to a hard
>> error.
>> 
>> So why must we be so tough?
>> 
>
> Because -std=legacy allows a whole bunch of garbage.
>
> Instead of fixing broken code, a user will slap -std=legacy
> in a Makefile and move on.  Then years from now, you'll see
> -std=legacy in a whole bunch of Makefiles whether it is needed
> or not.  See -maligned-double and -fallow-argument-mismatch as
> poster children.

I agree that this is what will happen.  But for people running benchmarks,
it's kind-of (kind-of) a feature.  Benchmarks tend to include relatively
old code by the time that they're released, and benchmarks continue to be
relevant (or at least widely tested) after they're out of maintenance.

So it has been really useful to have -std=legacy accept old, dangerous code,
since it means that we can continue to test old benchmarks with newer
compilers.  Improving the benchmark source to avoid the dangerous constructs
would invalidate the test and make it harder to compare with historical
results.

> Again, just my $0.02.

Same here, just wanted to raise the benchmark use case.

Thanks,
Richard


Re: [PATCH] Fortran: different character lengths in array constructor [PR93289]

2025-02-03 Thread Jerry D

On 2/3/25 2:49 AM, Richard Sandiford wrote:

Steve Kargl  writes:

On Sat, Feb 01, 2025 at 09:49:17PM +0100, Harald Anlauf wrote:

Am 01.02.25 um 21:03 schrieb Steve Kargl:

On Sat, Feb 01, 2025 at 07:25:51PM +0100, Harald Anlauf wrote:


the attached patch downgrades different constant character lengths in an
array constructor from a GNU to a legacy extension, so that users get a
warning with -std=gnu.  We continue to generate an error when standard
conformance is requested.

Regtested on x86_64-pc-linux-gnu (found one testcase where this
triggered... :)

OK for mainline?



My vote is 'no'.

This is either a GNU extension or an error.  It is certainly
not a legacy issue as array constructors simple cannot appear
old moldy *legacy* codes.


legacy /= moldy.

My intention is to downgrade existing, potentially dangerous
GNU extensions (like this one) carefully to "legacy", but not
with an axe.


I would be in favor of making it a hard error.  If you believe
gfortan must be able to compile invalid source, then add an option
such as -fallow-invalid-scalar-character-entities-in-array-constructor.


I don't see why we shall scare users by making code that is currently
accepted silently, because it is a GNU extension, suddenly to a hard
error.

So why must we be so tough?



Because -std=legacy allows a whole bunch of garbage.

Instead of fixing broken code, a user will slap -std=legacy
in a Makefile and move on.  Then years from now, you'll see
-std=legacy in a whole bunch of Makefiles whether it is needed
or not.  See -maligned-double and -fallow-argument-mismatch as
poster children.


I agree that this is what will happen.  But for people running benchmarks,
it's kind-of (kind-of) a feature.  Benchmarks tend to include relatively
old code by the time that they're released, and benchmarks continue to be
relevant (or at least widely tested) after they're out of maintenance.

So it has been really useful to have -std=legacy accept old, dangerous code,
since it means that we can continue to test old benchmarks with newer
compilers.  Improving the benchmark source to avoid the dangerous constructs
would invalidate the test and make it harder to compare with historical
results.


Again, just my $0.02.


Same here, just wanted to raise the benchmark use case.

Thanks,
Richard


I think we have had good discussion and for sake of the good of the 
order I recommend we push this for now.  The work has been done.


Regards,

Jerry


How to do a seek (nonadvancing read) on a stream file?

2025-02-03 Thread Andi McClure
 Last week, as an exercise in learning FORTRAN, I did a programming puzzle
( https://adventofcode.com/2024/day/4 ) with gfortran. I targeted the 2023
standard (*not* GNU). I saw two oddities. The first I posted about in this
mailing list already (and it turns out there is a relevant bugzilla bug).
The other I *think* is a bug (and I am not finding an existing bugzilla bug
on my own), but I am less sure, so wanted to check here first before filing.

For my solution, I needed to read in a file in stream mode, character by
character(1). I needed to do this twice, once to find out what size array
to load the data into and once to load the data into my newly-allocated
array. It initially appeared stream mode would allow me to do this without
closing and reopening the file, by "seeking" back to the beginning of the
file using the pos= argument to READ. But when I tried to do this,
something odd happened.

Details: I open the file with

```
open(10,file=path,access='stream',form='unformatted',action='read',iostat=file_error)
```

This works; scanning to determine the input size works. Now I need to seek.
I find this old stackoverflow answer: https://stackoverflow.com/a/11785795

Claiming that the following code works (and implying they tested it in "
ifort"):

```
READ (iu,"()", ADVANCE='NO', POS=file_pos) ! iu is file unit
```

I created a test program implementing this:

https://github.com/mcclure/aoc2024/blob/38875a77fd48d8208ebcadfb3ec9c53fb722ef8b/04-01-wordsearch/src/puzzle.f90#L4

And using a test input such as:

https://github.com/mcclure/aoc2024/blob/38875a77fd48d8208ebcadfb3ec9c53fb722ef8b/04-01-wordsearch/data/sample-2.18.txt

I can run it with `gfortran src/puzzle.f90 -std=f2023 -o program &&
./program data/sample-2.18.txt`. When I do this, I get a failure:

```
At line 88 of file src/puzzle.f90 (unit = 10, file = 'data/sample-2.18.txt')
Fortran runtime error: Format present for UNFORMATTED data transfer
```

It appears it does not like the "()" format. However, imagine I edit line
88 to change `read(10, "()", advance='no', pos=1)` to `read(10,
advance='no', pos=1)`, removing the format. Now I get a different error:

```
./program data/sample-2.18.txt
src/puzzle.f90:88:21:

   88 | read(10, advance='no', pos=1)
  | 1
Error: the ADVANCE= specifier at (1) must appear with an explicit format
expression
```

So if I have a (null) format specifier the error message tells me to remove
the format expression, and if I remove the format specifier the error
message tells me to add a format expression. There appears to be *no way*
of using advance='no' that will not cause gfortran to emit an error; even
putting in a (spurious/useless) read, such as with `read(10, "(a)",
advance='no', pos=1) char_in`, produces "Fortran runtime error: Format
present for UNFORMATTED data transfer".

I do not have a specific need for this to be fixed; I eventually got my
program to work via a workaround I would consider "silly" ( see line 102:
https://github.com/mcclure/aoc2024/blob/ca77f141f33ab494dc1bb43f3d6f13e775a36303/04-01-wordsearch/src/puzzle.f90#L102
). However it seems like there is a bug here, for three reasons: because
having some method of seeking the file without simultaneously doing a read
is fundamentally desirable; because the error messages seem to give
misleading directions; and because I *think* this is a standard
nonconformance.

If I look at the current standard ( 2023 draft document:
https://j3-fortran.org/doc/year/23/23-007r1.pdf ) under the definition of
io-control-spec I see;

> C1223 (R1213) An ADVANCE= specifier shall appear only in a formatted
sequential or stream data transfer25
> statement with explicit format specification (13.2) whose
io-control-spec-list does not contain an internal-26
> file-variable as the io-unit.

This implies an io-control-spec-list with *no* "io-unit" should be allowed.
I find this same text (with different numbering) in drafts of the 2008 and
2003 standards, so it appears this has been part of FORTRAN as long as
stream mode itself.

Does anyone know of an impediment to filing this (am I doing something
wrong, is there an existing bug I was not able to find(2))?

---

(1) I understand use of stream mode is considered unusual. The problem I
was solving here was a rare case it was actually appropriate: the input
file, linked above as "test input", was a grid of ASCII art.

(2) I think I have the hang of using the mailing list now, so I expect I
will actually see the reply this time *_*


Re: [patch, fortran] Add modular exponentiation for unsigned

2025-02-03 Thread Thomas Koenig

Hi Jerry,

committed as r15-7345 .

Thanks for the review!

Best regards

Thomas



Re: [patch, fortran] Add modular exponentiation for unsigned

2025-02-03 Thread Thomas Koenig




Regression-tested on x86_64.


Seems I didn't look closely enough, I will check and resubmit.

Best regards

Thomas