Re: [PATCH v5 4/5] c++modules: report imported CMI files as dependencies
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?
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?
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]
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?
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?
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
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 +