Re: Testing for prototypes generated from Fortran

2025-05-11 Thread Richard Biener
On Sun, May 11, 2025 at 8:38 PM Harald Anlauf  wrote:
>
> Hi Thomas,
>
> Am 11.05.25 um 12:51 schrieb Thomas Koenig via Gcc:
> > Hi Harald,
> >
> >> Hi Thomas,
> >>
> >> On 5/11/25 10:34, Thomas Koenig via Gcc wrote:
> >>> As PR120139 has shown (again), it is too easy to create regressions
> >>> for dumping C prototypes from Fortran.  The main problem
> >>> is that there is currently no test in the testsuite.
> >>>
> >
> >> for something along this variant you can try multiline-output
> >> as in the attached sample.
> >>
> >> There may be better ways...
> >
> > Hm, this could work. This would have the disadvantage that any
> > change to the generated file would show up as "regression" on
> > testing, even if it was not relevant to the test.
> >
> > Is there maybe something along the lines of "match the compiler
> > output for a certain pattern and discard everything else" in
> > dejagnu? I tried finding it in the docs, but I didn't find anything
> > that would work.
>
> the only thing that I am aware is writing multiple dg-output's with
> suitable regexes.  This allow to check that something is *present*,
> but I did not find the negation, i.e. absence of something not wanted.

I would suggest to try writing some new dejagnu harness that has
a two-stage compilation, generating the C prototypes from fortran
part of a testcase and compiling a C part of a testcase using the
prototypes.  I'm not sure whether eventually you can achieve this
with

! { dg-options "-fc-prototypes" }
! { dg-additional-sources "foo.c" }

aka, whether foo.c is then reliably compiled _after_ the fortran source

Richard.

> Good luck,
> Harald
>
> > Best regards
> >
> >  Thomas
> >
> >
>


[PATCH] fortran, v2: Fix up minloc/maxloc lowering [PR120191]

2025-05-11 Thread Jakub Jelinek
On Sat, May 10, 2025 at 11:21:19AM +0200, Tobias Burnus wrote:
> Namely: Similar to above, we should be able to just do:
> 
>    if (dim_arg->expr)
> 
> I think the comment should be also updated and we
> can also get rid of the 'actual' variable for cleanup.
> 
> Namely, something like the following on top of your patch (untested):

Here is an updated patch including your incremental changes.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

Trying to write a testcase I've run into further issues but seems they
are on the library side, so I'll post it incrementally.

2025-05-12  Jakub Jelinek  
Daniil Kochergin  
Tobias Burnus  

PR fortran/120191
* trans-intrinsic.cc (strip_kind_from_actual): Remove.
(gfc_conv_intrinsic_minmaxloc): Don't call strip_kind_from_actual.
Free and clear kind_arg->expr if non-NULL.  Set back_arg->name to
"%VAL" instead of a loop looking for last argument.  Remove actual
variable, use array_arg instead.  Free and clear dim_arg->expr if
non-NULL for BT_CHARACTER cases instead of using a loop.

* gfortran.dg/pr120191_1.f90: New test.

--- gcc/fortran/trans-intrinsic.cc.jj   2025-04-22 21:26:15.772920190 +0200
+++ gcc/fortran/trans-intrinsic.cc  2025-05-10 21:25:24.541308686 +0200
@@ -4715,22 +4715,6 @@ maybe_absent_optional_variable (gfc_expr
 }
 
 
-/* Remove unneeded kind= argument from actual argument list when the
-   result conversion is dealt with in a different place.  */
-
-static void
-strip_kind_from_actual (gfc_actual_arglist * actual)
-{
-  for (gfc_actual_arglist *a = actual; a; a = a->next)
-{
-  if (a && a->name && strcmp (a->name, "kind") == 0)
-   {
- gfc_free_expr (a->expr);
- a->expr = NULL;
-   }
-}
-}
-
 /* Emit code for minloc or maxloc intrinsic.  There are many different cases
we need to handle.  For performance reasons we sometimes create two
loops instead of one, where the second one is much simpler.
@@ -4925,7 +4909,7 @@ gfc_conv_intrinsic_minmaxloc (gfc_se * s
   tree b_if, b_else;
   tree back;
   gfc_loopinfo loop, *ploop;
-  gfc_actual_arglist *actual, *array_arg, *dim_arg, *mask_arg, *kind_arg;
+  gfc_actual_arglist *array_arg, *dim_arg, *mask_arg, *kind_arg;
   gfc_actual_arglist *back_arg;
   gfc_ss *arrayss = nullptr;
   gfc_ss *maskss = nullptr;
@@ -4944,8 +4928,7 @@ gfc_conv_intrinsic_minmaxloc (gfc_se * s
   int n;
   bool optional_mask;
 
-  actual = expr->value.function.actual;
-  array_arg = actual;
+  array_arg = expr->value.function.actual;
   dim_arg = array_arg->next;
   mask_arg = dim_arg->next;
   kind_arg = mask_arg->next;
@@ -4954,14 +4937,16 @@ gfc_conv_intrinsic_minmaxloc (gfc_se * s
   bool dim_present = dim_arg->expr != nullptr;
   bool nested_loop = dim_present && expr->rank > 0;
 
-  /* The last argument, BACK, is passed by value. Ensure that
- by setting its name to %VAL. */
-  for (gfc_actual_arglist *a = actual; a; a = a->next)
+  /* Remove kind.  */
+  if (kind_arg->expr)
 {
-  if (a->next == NULL)
-   a->name = "%VAL";
+  gfc_free_expr (kind_arg->expr);
+  kind_arg->expr = NULL;
 }
 
+  /* Pass BACK argument by value.  */
+  back_arg->name = "%VAL";
+
   if (se->ss)
 {
   if (se->ss->info->useflags)
@@ -4983,25 +4968,19 @@ gfc_conv_intrinsic_minmaxloc (gfc_se * s
}
 }
 
-  arrayexpr = actual->expr;
+  arrayexpr = array_arg->expr;
 
-  /* Special case for character maxloc.  Remove unneeded actual
- arguments, then call a library function.  */
+  /* Special case for character maxloc.  Remove unneeded "dim" actual
+ argument, then call a library function.  */
 
   if (arrayexpr->ts.type == BT_CHARACTER)
 {
   gcc_assert (expr->rank == 0);
 
-  gfc_actual_arglist *a = actual;
-  strip_kind_from_actual (a);
-  while (a)
+  if (dim_arg->expr)
{
- if (a->name && strcmp (a->name, "dim") == 0)
-   {
- gfc_free_expr (a->expr);
- a->expr = NULL;
-   }
- a = a->next;
+ gfc_free_expr (dim_arg->expr);
+ dim_arg->expr = NULL;
}
   gfc_conv_intrinsic_funcall (se, expr);
   return;
--- gcc/testsuite/gfortran.dg/pr120191_1.f90.jj 2025-05-09 17:19:07.905018604 
+0200
+++ gcc/testsuite/gfortran.dg/pr120191_1.f902025-05-09 17:19:07.905018604 
+0200
@@ -0,0 +1,614 @@
+! PR fortran/120191
+! { dg-do run }
+
+  integer(kind=1) :: a1(10, 10, 10), b1(10)
+  integer(kind=2) :: a2(10, 10, 10), b2(10)
+  integer(kind=4) :: a4(10, 10, 10), b4(10)
+  integer(kind=8) :: a8(10, 10, 10), b8(10)
+  real(kind=4) :: r4(10, 10, 10), s4(10)
+  real(kind=8) :: r8(10, 10, 10), s8(10)
+  logical :: l1(10, 10, 10), l2(10), l3
+  l1 = .true.
+  l2 = .true.
+  l3 = .true.
+  a1 = 0
+  if (any (maxloc (a1) .ne. 1)) stop 1
+  if (any (maxloc (a1, back=.false.) .ne. 1)) stop 2
+  if (any (maxloc (a1, back=.true.) .ne. 10)) stop 3
+  if (a

[PATCH] fortran: map atand(y, x) to atan2d(y, x)

2025-05-11 Thread Yuao Ma
Hi all,

According to the Fortran standard, atand(y, x) is equivalent to atan2d(y, x).
However, the current atand(y, x) function produces an error. This patch
includes the necessary intrinsic mapping, related test, and intrinsic
documentation.
The minor comment change in intrinsic.cc is cherry-picked from Steve's previous
work.

Best regards,
Yuao



0001-fortran-map-atand-y-x-to-atan2d-y-x.patch
Description: 0001-fortran-map-atand-y-x-to-atan2d-y-x.patch


Re: [PATCH] fortran: map atand(y, x) to atan2d(y, x)

2025-05-11 Thread Tobias Burnus

Hi all, hi Yuao,

first, thanks for your patch - you are awesome! I believe it fixes the
issue reported by Steven in problem report (PR) 113414,
https://gcc.gnu.org/PR113413

Thus:

* * *

[Linking PR numbers]

In order to correlate commits to issued (and get them automatically
linked), the commit log should contain a reference.

The syntax is  + "PR " + space +  + "/" + number,
i.e. here: (tab) PR fortran/113413.

However, when using mklog.py, it takes already care of the syntax:

* Use '-b' to specify the bug number or
* If in the first few lines of a (test) file, a PRxxx or
  PR comp/xxx appears, mklog.py assumes that's a PR number.

Unless you already use 'PR comp/123", this doesn't automatically
add the component to the commit changelog. However, if you invoke
mklog.py with '-p', it queries Bugzilla – and fills in the component.
Additionally, '-p' includes the bug title(s) in the template; that's a
good way to cross check the number as it is easily to mistype a longer
number.

[PR number in the commit/email subject]

Consider to add the PR number to the mail – most common is to append
[PR1234] at the end (i.e. without component). However, there are no firm
rules about this. Sometimes, leaving it out completely make most sense
(e.g. if several bugs are fixed) or if the subject line already very long;
additionally, different persons have different styles - and use a different
style.

* * *

(Pre-existing documentation issue, but should be fixed alongside:)

Looking at the documentation and comparing ATAND to ATAN,
https://gcc.gnu.org/onlinedocs/gfortran/ATAND.html and
https://gcc.gnu.org/onlinedocs/gfortran/ATAN.html

* Synopsis should also show the two-argument version
* "ifY is present,X shall be REAL" does no make sense as ATAND
  (contrary to ATAN) does not permit complex values
* Something like "If Y is present, the result is identical to
  ATAN2D(Y,X). Otherwise," is missing.
* "range -90 \leq \Re \atand(x) \leq 90": the 'Re' IMHO doesn't
  make   sense as the argument must always be real.

* * *

[I have still to look at the rest of the patch, but at a glance it
looks fine.]

Thanks again for your patch!

Tobias



Re: Testing for prototypes generated from Fortran

2025-05-11 Thread Thomas Koenig

Hi Harald,


Hi Thomas,

On 5/11/25 10:34, Thomas Koenig via Gcc wrote:

As PR120139 has shown (again), it is too easy to create regressions
for dumping C prototypes from Fortran.  The main problem
is that there is currently no test in the testsuite.




for something along this variant you can try multiline-output
as in the attached sample.

There may be better ways...


Hm, this could work. This would have the disadvantage that any
change to the generated file would show up as "regression" on
testing, even if it was not relevant to the test.

Is there maybe something along the lines of "match the compiler
output for a certain pattern and discard everything else" in
dejagnu? I tried finding it in the docs, but I didn't find anything
that would work.

Best regards

Thomas



Testing for prototypes generated from Fortran

2025-05-11 Thread Thomas Koenig

As PR120139 has shown (again), it is too easy to create regressions
for dumping C prototypes from Fortran.  The main problem
is that there is currently no test in the testsuite.

So, what to do?  I see several possibilities:

1a) Change the relevant options so that they optionally
create a file (something like -fc-prototypes=filename.h)
and then scan for the presence/absence of patterns in that
file.  (Is it OK just to open and close a file anywhere
in the front end?). The generated files should then be
removed afterwards (how?).

1b) Instead of checking for patterns in the output create a header file
which is then included in a C file for testing.  Same questions
as above, with the additional question on how to ensure that
compilation of the C file only happens after the header file
has been generated.

2) Dump to standard output and check for the presence of certain
regexps, ignoring anything else.  Again, this is something I don't
know how to do.

This is really something I would like to have fixed for gcc-16.

Other ideas? Comments? Suggestions?

Best regards

Thomas




Re: Testing for prototypes generated from Fortran

2025-05-11 Thread Harald Anlauf

Hi Thomas,

On 5/11/25 10:34, Thomas Koenig via Gcc wrote:

As PR120139 has shown (again), it is too easy to create regressions
for dumping C prototypes from Fortran.  The main problem
is that there is currently no test in the testsuite.

So, what to do?  I see several possibilities:

1a) Change the relevant options so that they optionally
create a file (something like -fc-prototypes=filename.h)
and then scan for the presence/absence of patterns in that
file.  (Is it OK just to open and close a file anywhere
in the front end?). The generated files should then be
removed afterwards (how?).

1b) Instead of checking for patterns in the output create a header file
which is then included in a C file for testing.  Same questions
as above, with the additional question on how to ensure that
compilation of the C file only happens after the header file
has been generated.

2) Dump to standard output and check for the presence of certain
regexps, ignoring anything else.  Again, this is something I don't
know how to do.


for something along this variant you can try multiline-output
as in the attached sample.

There may be better ways...

Cheers,
Harald


This is really something I would like to have fixed for gcc-16.

Other ideas? Comments? Suggestions?

Best regards

 Thomas



! { dg-options "-fc-prototypes" }

subroutine foo (x, k) bind(c)
  integer, value :: k
  real   :: x(k)
end

#if 0
{ dg-begin-multiline-output "" }
#include 
#ifdef __cplusplus
#include 
#define __GFORTRAN_FLOAT_COMPLEX std::complex
#define __GFORTRAN_DOUBLE_COMPLEX std::complex
#define __GFORTRAN_LONG_DOUBLE_COMPLEX std::complex
extern "C" {
#else
#define __GFORTRAN_FLOAT_COMPLEX float _Complex
#define __GFORTRAN_DOUBLE_COMPLEX double _Complex
#define __GFORTRAN_LONG_DOUBLE_COMPLEX long double _Complex
#endif

void foo (float x /* WARNING: non-interoperable KIND */ , int k /* WARNING: non-interoperable KIND */ );

#ifdef __cplusplus
}
#endif
{ dg-end-multiline-output "" }
#endif


Re: Testing for prototypes generated from Fortran

2025-05-11 Thread Harald Anlauf

Hi Thomas,

Am 11.05.25 um 12:51 schrieb Thomas Koenig via Gcc:

Hi Harald,


Hi Thomas,

On 5/11/25 10:34, Thomas Koenig via Gcc wrote:

As PR120139 has shown (again), it is too easy to create regressions
for dumping C prototypes from Fortran.  The main problem
is that there is currently no test in the testsuite.




for something along this variant you can try multiline-output
as in the attached sample.

There may be better ways...


Hm, this could work. This would have the disadvantage that any
change to the generated file would show up as "regression" on
testing, even if it was not relevant to the test.

Is there maybe something along the lines of "match the compiler
output for a certain pattern and discard everything else" in
dejagnu? I tried finding it in the docs, but I didn't find anything
that would work.


the only thing that I am aware is writing multiple dg-output's with
suitable regexes.  This allow to check that something is *present*,
but I did not find the negation, i.e. absence of something not wanted.

Good luck,
Harald


Best regards

 Thomas






Re: Testing for prototypes generated from Fortran

2025-05-11 Thread Ben Boeckel
On Sun, May 11, 2025 at 10:34:11 +0200, Thomas Koenig via Gcc wrote:
> 2) Dump to standard output and check for the presence of certain
> regexps, ignoring anything else.  Again, this is something I don't
> know how to do.

This is…fraught with peril and fiddliness. If the test can stomach some
C++, you can use `` to `static_assert` on declaration
properties. See this test as an example of how we ensure ABI stability
as far as the header is concerned:


https://gitlab.kitware.com/paraview/catalyst/-/blob/master/tests/abi_tests/test_catalyst_abi.cpp

--Ben