Re: [PATCH v5 4/5] c++modules: report imported CMI files as dependencies

2023-07-27 Thread Jason Merrill via Fortran

On 7/23/23 20:26, Ben Boeckel wrote:

On Fri, Jul 21, 2023 at 16:23:07 -0400, Nathan Sidwell wrote:

It occurs to me that the model I am envisioning is similar to CMake's object
libraries.  Object libraries are a convenient name for a bunch of object files.
IIUC they're linked by naming the individual object files (or I think the could
be implemented as a static lib linked with --whole-archive path/to/libfoo.a
-no-whole-archive.  But for this conversation consider them a bunch of separate
object files with a convenient group name.


Yes, `--whole-archive` would work great if it had any kind of
portability across CMake's platform set.


Consider also that object libraries could themselves contain object libraries (I
don't know of they can, but it seems like a useful concept).  Then one could
create an object library from a collection of object files and object libraries
(recursively).  CMake would handle the transitive gtaph.


I think this detail is relevant, but you can use
`$` as an `INTERFACE` sources and it would act
like that, but it is an explicit thing. Instead, `OBJECT` libraries
*only* provide their objects to targets that *directly* link them. If
not, given this:

 A (OBJECT library)
 B (library of some kind; links PUBLIC to A)
 C (links to B)

If `A` has things like linker flags (or, more likely, libraries) as part
of its usage requirements, C will get them on is link line. However, if
OBJECT files are transitive in the same way, the linker (on most
platforms at least) chokes because it now has duplicates of all of A's
symbols: those from the B library and those from A's objects on the link
line.


Now, allow an object library to itself have some kind of tangible, on-disk
representation.  *BUT* not like a static library -- it doesn't include the
object files.


Now that immediately maps onto modules.

CMI: Object library
Direct imports: Direct object libraries of an object library

This is why I don't understand the need explicitly indicate the indirect imports
of a CMI.  CMake knows them, because it knows the graph.


Sure, *CMake* knows them, but the *build tool* needs to be told
(typically `make` or `ninja`) because it is what is actually executing
the build graph. The way this is communicated is via `-MF` files and
that's what I'm providing in this patch. Note that `ninja` does not
allow rules to specify such dependencies for other rules than the one it
is reading the file for.


But since the direct imports need to be rebuilt themselves if the 
transitive imports change, the build graph should be the same whether or 
not the transitive imports are repeated?  Either way, if a transitive 
import changes you need to rebuild the direct import and then the importer.


I guess it shouldn't hurt to have the transitive imports in the -MF 
file, as long as they aren't also in the p1689 file, so I'm not 
particularly opposed to this change, but I don't see how it makes a 
practical difference.


Jason



Re: Compile antiquated fortran?

2023-07-27 Thread Allin Cottrell via Fortran

On Thu, 27 Jul 2023, Jerry D wrote:


On 7/27/23 1:36 PM, Allin Cottrell via Fortran wrote:
I have old fortran source code (not my own work) for a specialized 
statistical program that I and others find quite useful.


A few years ago I was able to compile it on Linux using gfortran with 
std=legacy (and also cross-compile it for Windows an Mac). Now I'd like to 
rebuild it, but with recent gfortran (I've tried 12.2.1 on Fedora and 
13.1.1 on Arch) it's a no-go. I get lots of errors of the following sort:


ansub9.f:151:44:

   151 |    INTEGER ITYPE,INIT,LAM,IMEAN,IP,ID,Q,BP,BD,BQ,SQG,MQ,L,M,
   |   1
Error: Symbol ‘q’ at (1) already has basic type of REAL

I can understand this complaint. The code contains this sort of thing 
within a given subroutine:


    IMPLICIT  REAL*8 (A-H,O-Z)


Have you considered replacing the above line with IMPLICIT NONE and add 
explicit declarations as needed? The code will be safer in the long run.


That would be a good solution, for sure, but I don't think I 
understand the original code well enough to make the required 
changes.


Meanwhile, though, Steve Kargl has suggested a nice fix which just 
involved moving one block of the code.


Allin Cottrell


Re: Compile antiquated fortran?

2023-07-27 Thread Jerry D via Fortran

On 7/27/23 1:36 PM, Allin Cottrell via Fortran wrote:
I have old fortran source code (not my own work) for a specialized 
statistical program that I and others find quite useful.


A few years ago I was able to compile it on Linux using gfortran with 
std=legacy (and also cross-compile it for Windows an Mac). Now I'd like 
to rebuild it, but with recent gfortran (I've tried 12.2.1 on Fedora and 
13.1.1 on Arch) it's a no-go. I get lots of errors of the following sort:


ansub9.f:151:44:

   151 |    INTEGER ITYPE,INIT,LAM,IMEAN,IP,ID,Q,BP,BD,BQ,SQG,MQ,L,M,
   |   1
Error: Symbol ‘q’ at (1) already has basic type of REAL

I can understand this complaint. The code contains this sort of thing 
within a given subroutine:


    IMPLICIT  REAL*8 (A-H,O-Z)


Have you considered replacing the above line with IMPLICIT NONE and add 
explicit declarations as needed? The code will be safer in the long run.



Regards,

Jerry


[PATCH] Fortran: do not pass hidden character length for TYPE(*) dummy [PR110825]

2023-07-27 Thread Harald Anlauf via Fortran
Dear all,

when passing a character actual argument to an assumed-type dummy
(TYPE(*)), we should not pass the character length for that argument,
as otherwise other hidden arguments that are passed as part of the
gfortran ABI will not be interpreted correctly.  This is in line
with the current way the procedure decl is generated.

The attached patch fixes the caller and clarifies the behavior
in the documentation.

Regtested on x86_64-pc-linux-gnu.  OK for mainline?

Thanks,
Harald

From 199e09c9862f5afe7e583839bc1b108c741a7efb Mon Sep 17 00:00:00 2001
From: Harald Anlauf 
Date: Thu, 27 Jul 2023 21:30:26 +0200
Subject: [PATCH] Fortran: do not pass hidden character length for TYPE(*)
 dummy [PR110825]

gcc/fortran/ChangeLog:

	PR fortran/110825
	* gfortran.texi: Clarify argument passing convention.
	* trans-expr.cc (gfc_conv_procedure_call): Do not pass the character
	length as hidden argument when the declared dummy argument is
	assumed-type.

gcc/testsuite/ChangeLog:

	PR fortran/110825
	* gfortran.dg/assumed_type_18.f90: New test.
---
 gcc/fortran/gfortran.texi |  3 +-
 gcc/fortran/trans-expr.cc |  1 +
 gcc/testsuite/gfortran.dg/assumed_type_18.f90 | 52 +++
 3 files changed, 55 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gfortran.dg/assumed_type_18.f90

diff --git a/gcc/fortran/gfortran.texi b/gcc/fortran/gfortran.texi
index 7786d23265f..f476a3719f5 100644
--- a/gcc/fortran/gfortran.texi
+++ b/gcc/fortran/gfortran.texi
@@ -3750,7 +3750,8 @@ front ends of GCC, e.g. to GCC's C99 compiler for @code{_Bool}
 or GCC's Ada compiler for @code{Boolean}.)

 For arguments of @code{CHARACTER} type, the character length is passed
-as a hidden argument at the end of the argument list.  For
+as a hidden argument at the end of the argument list, except when the
+corresponding dummy argument is declared as @code{TYPE(*)}.  For
 deferred-length strings, the value is passed by reference, otherwise
 by value.  The character length has the C type @code{size_t} (or
 @code{INTEGER(kind=C_SIZE_T)} in Fortran).  Note that this is
diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc
index ef3e6d08f78..764565476af 100644
--- a/gcc/fortran/trans-expr.cc
+++ b/gcc/fortran/trans-expr.cc
@@ -7521,6 +7521,7 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
 	  && !(fsym && fsym->ts.type == BT_DERIVED && fsym->ts.u.derived
 	   && fsym->ts.u.derived->intmod_sym_id == ISOCBINDING_PTR
 	   && fsym->ts.u.derived->from_intmod == INTMOD_ISO_C_BINDING )
+	  && !(fsym && fsym->ts.type == BT_ASSUMED)
 	  && !(fsym && UNLIMITED_POLY (fsym)))
 	vec_safe_push (stringargs, parmse.string_length);

diff --git a/gcc/testsuite/gfortran.dg/assumed_type_18.f90 b/gcc/testsuite/gfortran.dg/assumed_type_18.f90
new file mode 100644
index 000..a3d791919a2
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/assumed_type_18.f90
@@ -0,0 +1,52 @@
+! { dg-do run }
+! PR fortran/110825 - TYPE(*) and character actual arguments
+
+program foo
+  use iso_c_binding, only: c_loc, c_ptr, c_associated
+  implicit none
+  character(100):: not_used = ""
+  character(:), allocatable :: deferred
+  character :: c42(6,7) = "*"
+  call sub  (not_used,  "123")
+  call sub  ("0"  , "123")
+  deferred = "d"
+  call sub  (deferred , "123")
+  call sub2 ([1.0,2.0], "123")
+  call sub2 (["1","2"], "123")
+  call sub3 (c42  , "123")
+
+contains
+
+  subroutine sub (useless_var, print_this)
+type(*),  intent(in) :: useless_var
+character(*), intent(in) :: print_this
+if (len  (print_this) /= 3) stop 1
+if (len_trim (print_this) /= 3) stop 2
+  end
+
+  subroutine sub2 (a, c)
+type(*),  intent(in) :: a(:)
+character(*), intent(in) :: c
+if (len  (c) /= 3) stop 10
+if (len_trim (c) /= 3) stop 11
+if (size (a) /= 2) stop 12
+  end
+
+  subroutine sub3 (a, c)
+type(*),  intent(in), target, optional :: a(..)
+character(*), intent(in)   :: c
+type(c_ptr) :: cpt
+if (len  (c) /= 3) stop 20
+if (len_trim (c) /= 3) stop 21
+if (.not. present (a)) stop 22
+if (rank (a) /= 2) stop 23
+if (size (a)/= 42) stop 24
+if (any (shape  (a) /= [6,7])) stop 25
+if (any (lbound (a) /= [1,1])) stop 26
+if (any (ubound (a) /= [6,7])) stop 27
+if (.not. is_contiguous (a))   stop 28
+cpt = c_loc (a)
+if (.not. c_associated (cpt))  stop 29
+  end
+
+end
--
2.35.3



Re: Compile antiquated fortran?

2023-07-27 Thread Steve Kargl via Fortran
On Thu, Jul 27, 2023 at 01:36:46PM -0400, Allin Cottrell via Fortran wrote:
> I have old fortran source code (not my own work) for a specialized
> statistical program that I and others find quite useful.
> 
> A few years ago I was able to compile it on Linux using gfortran with
> std=legacy (and also cross-compile it for Windows an Mac). Now I'd like to
> rebuild it, but with recent gfortran (I've tried 12.2.1 on Fedora and 13.1.1
> on Arch) it's a no-go. I get lots of errors of the following sort:
> 
> ansub9.f:151:44:
> 
>   151 |INTEGER ITYPE,INIT,LAM,IMEAN,IP,ID,Q,BP,BD,BQ,SQG,MQ,L,M,
>   |   1
> Error: Symbol ‘q’ at (1) already has basic type of REAL
> 
> I can understand this complaint. The code contains this sort of thing within
> a given subroutine:
> 
>IMPLICIT  REAL*8 (A-H,O-Z)
> 
> then some lines later on:
> 
>INTEGER ITYPE,INIT,LAM,IMEAN,P,D,Q,...
> 
> I guess the author was assuming that an explicit type-assignment just
> overrides an implicit one. Older gfortran apparently played along with that.
> 
> My question: Given that I'm already using -std=legacy, are there any other
> flags that I could add to get the code to compile?
> 
> (I know I could tackle this by renaming a bunch of variables, but in context
> that would be an extremely fiddly job.)
> 

I'm afraid we'll need to see some actual code.  The following compiles
without a problem.

   SUBROUTINE FOO(Q)
   IMPLICIT REAL*8 (A-H,O-Z)
   INTEGER Q
   Q = 1
   END

Hmmm, are DATA statements in the code?

   SUBROUTINE FOO
   IMPLICIT REAL*8 (A-H,O-Z)
   DATA Q/1/
   INTEGER Q
   Q = 1
   END

% gfortran12 -c -Wall a.f
a.f:4:16:

4 |INTEGER Q
  |1
Error: Symbol 'q' at (1) already has basic type of REAL

gfortran is correct to complain here.  The DATA statement give
Q a REAL type due to the implicit statement.  Q can only appear
in a later declaration statement that re-affirms that type.

-- 
Steve


Compile antiquated fortran?

2023-07-27 Thread Allin Cottrell via Fortran
I have old fortran source code (not my own work) for a specialized 
statistical program that I and others find quite useful.


A few years ago I was able to compile it on Linux using gfortran 
with std=legacy (and also cross-compile it for Windows an Mac). Now 
I'd like to rebuild it, but with recent gfortran (I've tried 12.2.1 
on Fedora and 13.1.1 on Arch) it's a no-go. I get lots of errors of 
the following sort:


ansub9.f:151:44:

  151 |INTEGER ITYPE,INIT,LAM,IMEAN,IP,ID,Q,BP,BD,BQ,SQG,MQ,L,M,
  |   1
Error: Symbol ‘q’ at (1) already has basic type of REAL

I can understand this complaint. The code contains this sort of 
thing within a given subroutine:


   IMPLICIT  REAL*8 (A-H,O-Z)

then some lines later on:

   INTEGER ITYPE,INIT,LAM,IMEAN,P,D,Q,...

I guess the author was assuming that an explicit type-assignment 
just overrides an implicit one. Older gfortran apparently played 
along with that.


My question: Given that I'm already using -std=legacy, are there any 
other flags that I could add to get the code to compile?


(I know I could tackle this by renaming a bunch of variables, but in 
context that would be an extremely fiddly job.)


Thanks for any help.

--
Allin Cottrell
Department of Economics
Wake Forest University


[committed] OpenMP/Fortran: Extend reject code between target + teams [PR71065, PR110725] (was: Re: [patch] OpenMP/Fortran: Reject declarations between target + teams (was: [Patch] OpenMP/Fortran: Rej

2023-07-27 Thread Tobias Burnus

Yet another omission, the flag was not properly set for deeply buried
'omp teams' as I stopped too early when walking up the stack.

Now fixed by commit r14-2826-g081e25d3cfd86c

* * *

This was found when 'repairing' the feature on the OG13
(devel/omp/gcc-13) branch for metadirectives, cf. the second attached
patch, applied after cherry-picking the mainline patch.

Tobias
-
Siemens Electronic Design Automation GmbH; Anschrift: Arnulfstraße 201, 80634 
München; Gesellschaft mit beschränkter Haftung; Geschäftsführer: Thomas 
Heurung, Frank Thürauf; Sitz der Gesellschaft: München; Registergericht 
München, HRB 106955
commit 081e25d3cfd86c4094999ded0bbe99b91762013c
Author: Tobias Burnus 
Date:   Thu Jul 27 18:14:11 2023 +0200

OpenMP/Fortran: Extend reject code between target + teams [PR71065, PR110725]

The previous version failed to diagnose when the 'teams' was nested
more deeply inside the target region, e.g. inside a DO or some
block or structured block.

PR fortran/110725
PR middle-end/71065

gcc/fortran/ChangeLog:

* openmp.cc (resolve_omp_target): Minor cleanup.
* parse.cc (decode_omp_directive): Find TARGET statement
also higher in the stack.

gcc/testsuite/ChangeLog:

* gfortran.dg/gomp/teams-6.f90: Extend.

diff --git a/gcc/fortran/openmp.cc b/gcc/fortran/openmp.cc
index 52eeaf2d4da..2952cd300ac 100644
--- a/gcc/fortran/openmp.cc
+++ b/gcc/fortran/openmp.cc
@@ -10666,15 +10666,14 @@ resolve_omp_target (gfc_code *code)
 
   if (!code->ext.omp_clauses->contains_teams_construct)
 return;
+  gfc_code *c = code->block->next;
   if (code->ext.omp_clauses->target_first_st_is_teams
-  && ((GFC_IS_TEAMS_CONSTRUCT (code->block->next->op)
-	   && code->block->next->next == NULL)
-	  || (code->block->next->op == EXEC_BLOCK
-	  && code->block->next->next
-	  && GFC_IS_TEAMS_CONSTRUCT (code->block->next->next->op)
-	  && code->block->next->next->next == NULL)))
+  && ((GFC_IS_TEAMS_CONSTRUCT (c->op) && c->next == NULL)
+	  || (c->op == EXEC_BLOCK
+	  && c->next
+	  && GFC_IS_TEAMS_CONSTRUCT (c->next->op)
+	  && c->next->next == NULL)))
 return;
-  gfc_code *c = code->block->next;
   while (c && !GFC_IS_TEAMS_CONSTRUCT (c->op))
 c = c->next;
   if (c)
diff --git a/gcc/fortran/parse.cc b/gcc/fortran/parse.cc
index aa6bb663def..e797402b59f 100644
--- a/gcc/fortran/parse.cc
+++ b/gcc/fortran/parse.cc
@@ -1318,32 +1318,27 @@ decode_omp_directive (void)
 case ST_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO:
 case ST_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
 case ST_OMP_TEAMS_LOOP:
-  if (gfc_state_stack->previous && gfc_state_stack->previous->tail)
-	{
-	  gfc_state_data *stk = gfc_state_stack;
-	  do {
-	   stk = stk->previous;
-	 } while (stk && stk->tail && stk->tail->op == EXEC_BLOCK);
-	  if (stk && stk->tail)
-	switch (stk->tail->op)
-	  {
-	  case EXEC_OMP_TARGET:
-	  case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE:
-	  case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD:
-	  case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO:
-	  case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
-	  case EXEC_OMP_TARGET_TEAMS_LOOP:
-	  case EXEC_OMP_TARGET_PARALLEL:
-	  case EXEC_OMP_TARGET_PARALLEL_DO:
-	  case EXEC_OMP_TARGET_PARALLEL_DO_SIMD:
-	  case EXEC_OMP_TARGET_PARALLEL_LOOP:
-	  case EXEC_OMP_TARGET_SIMD:
-		stk->tail->ext.omp_clauses->contains_teams_construct = 1;
-		break;
-	  default:
-	break;
-	  }
-	}
+  for (gfc_state_data *stk = gfc_state_stack->previous; stk;
+	   stk = stk->previous)
+	if (stk && stk->tail)
+	  switch (stk->tail->op)
+	{
+	case EXEC_OMP_TARGET:
+	case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE:
+	case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD:
+	case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO:
+	case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
+	case EXEC_OMP_TARGET_TEAMS_LOOP:
+	case EXEC_OMP_TARGET_PARALLEL:
+	case EXEC_OMP_TARGET_PARALLEL_DO:
+	case EXEC_OMP_TARGET_PARALLEL_DO_SIMD:
+	case EXEC_OMP_TARGET_PARALLEL_LOOP:
+	case EXEC_OMP_TARGET_SIMD:
+	  stk->tail->ext.omp_clauses->contains_teams_construct = 1;
+	  break;
+	default:
+	  break;
+	}
   break;
 case ST_OMP_ERROR:
   if (new_st.ext.omp_clauses->at != OMP_AT_EXECUTION)
diff --git a/gcc/testsuite/gfortran.dg/gomp/teams-6.f90 b/gcc/testsuite/gfortran.dg/gomp/teams-6.f90
index be453f27f40..0bd7735e738 100644
--- a/gcc/testsuite/gfortran.dg/gomp/teams-6.f90
+++ b/gcc/testsuite/gfortran.dg/gomp/teams-6.f90
@@ -37,6 +37,16 @@ end block
   i = 5
   !$omp end teams
 !$omp end target
+
+
+!$omp target  ! { dg-error "OMP TARGET region at .1. with a nested TEAMS may not contain any other statement, declaration or directive outside of the single TEAMS construct" }
+block
+  do i = 5, 8
+!$omp teams
+block; end block
+