# Fortitude 0.9.0 - release

**URL:** <https://fortran-lang.discourse.group/t/fortitude-0-9-0-release/10900>\
**Category:** Announcements\
**Created:** [May 13, 2026, 5:04pm UTC](https://fortran-lang.discourse.group/t/fortitude-0-9-0-release/10900 "2026-05-13T17:04:15Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![zedthree](https://avatars.discourse-cdn.com/v4/letter/z/f4b2a3/32.png) [@zedthree](https://fortran-lang.discourse.group/u/zedthree)\
**Post date:** [May 13, 2026, 5:04pm UTC](https://fortran-lang.discourse.group/t/fortitude-0-9-0-release/10900/1 "2026-05-13T17:04:15Z")

</div>

We’ve just released [Fortitude v0.9.0](https://github.com/PlasmaFAIR/fortitude/releases/tag/v0.9.0) 🎉

The main highlights:

- support for pFUnit `.pf` files
- support for `pyproject.toml` for configuration
- support for incremental linting on existing projects with `--git-staged` to run just on staged changes, and `--git-since` to run on changes since a particular commit/branch
- 14 new rules, bringing us to 101 rules total!
- 34 rules out of preview mode

As always, we’d love to hear your feedback and ideas for future features and rules, and please feel free to [raise an issue](https://github.com/PlasmaFAIR/fortitude/issues/new) if you run into any problems!

---

<div class="post-metadata">

**Author:** ![Simo](https://avatars.discourse-cdn.com/v4/letter/s/90db22/32.png) [@Simo](https://fortran-lang.discourse.group/u/Simo)\
**Post date:** [May 19, 2026, 6:01pm UTC](https://fortran-lang.discourse.group/t/fortitude-0-9-0-release/10900/2 "2026-05-19T18:01:26Z")

</div>

Nice work 🙂

I tried it on a few Fortran patterns that I would consider bug-prone. The two cases I could not get it to detect were:

1. `intent(out)` dummy arguments assigned only inside a conditional block:

```auto
subroutine set_value(flag, x)
   implicit none
   logical, intent(in) :: flag
   integer, intent(out) :: x
   
   if (flag) then
      x = 1
   end if

end subroutine set_value

```

1. Passing an N-D array to a routine that reinterprets it with a different **explicit** shape:

```auto
program demo
  implicit none
  integer :: x(3, 3, 3, 3) ! 4D array

  call fill_as_2d(x)

contains
  subroutine fill_as_2d(a)
     implicit none
     integer, intent(out) :: a(3,3) !!! < redefined as 2D array
     
     a = 1

  end subroutine fill_as_2d

end program demo

```

The second case is especially easy to miss because gfortran catches the mismatch if the dummy is assumed-shape, for example `a(:,:)`, but not when it is explicit-shape.

---

<div class="post-metadata">

**Author:** ![zedthree](https://avatars.discourse-cdn.com/v4/letter/z/f4b2a3/32.png) [@zedthree](https://fortran-lang.discourse.group/u/zedthree)\
**Post date:** [May 19, 2026, 7:46pm UTC](https://fortran-lang.discourse.group/t/fortitude-0-9-0-release/10900/3 "2026-05-19T19:46:34Z")

</div>

Thanks @Simo! Those are both great ideas for rules. The first one I think should be pretty easy to achieve, but the second one might be a little harder right now because it needs semantic information which might come from other modules, and currently we only collect it for local variables. However, the fact that it’s a bug and gfortran misses it means it would be really good if we could catch it.

I’ll make issues for both of these, they should definitely be on our radar.

---

<div class="post-metadata">

**Author:** ![Simo](https://avatars.discourse-cdn.com/v4/letter/s/90db22/32.png) [@Simo](https://fortran-lang.discourse.group/u/Simo)\
**Post date:** [May 19, 2026, 8:06pm UTC](https://fortran-lang.discourse.group/t/fortitude-0-9-0-release/10900/4 "2026-05-19T20:06:46Z")

</div>

Thank you!

If I understand correctly, the Fortran standard allows the second program (it’s not a bug when the shapes are specified explicitly), although I am pretty sure it’s bug-prone in practice, at least in my experience.

---

<div class="post-metadata">

**Author:** ![RonShepard](https://avatars.discourse-cdn.com/v4/letter/r/a3d4f5/32.png) [@RonShepard](https://fortran-lang.discourse.group/u/RonShepard)\
**Post date:** [May 20, 2026, 3:22am UTC](https://fortran-lang.discourse.group/t/fortitude-0-9-0-release/10900/5 "2026-05-20T03:22:43Z")

</div>

> [@Simo](#):
>
> If I understand correctly, the Fortran standard allows the second program […]

Both programs are standard conforming. That is, it is allowed to declare variables in an undefined state, or to perform some action that leaves a variable in an undefined state. The `intent(out)` declaration with no subsequent definition of that entity does that. And, as you say, it is also allowed to have array dimension and array rank mismatches with explicit shape declarations. That sometimes causes copy-in/copy-out argument association, but it is standard conforming.

---

<div class="post-metadata">

**Author:** ![Simo](https://avatars.discourse-cdn.com/v4/letter/s/90db22/32.png) [@Simo](https://fortran-lang.discourse.group/u/Simo)\
**Post date:** [May 20, 2026, 1:39pm UTC](https://fortran-lang.discourse.group/t/fortitude-0-9-0-release/10900/6 "2026-05-20T13:39:34Z")

</div>

I did not mean to say that the first program is not standard-conforming. As far as I know, that particular pitfall is already well known and has been discussed on this forum and elsewhere. My point was only that the second program is also standard-conforming, even though the first reaction many people might have when seeing it is: “This is definitely wrong.”

---

<div class="post-metadata">

**Author:** ![Beliavsky](https://avatars.discourse-cdn.com/v4/letter/b/ba8739/32.png) [@Beliavsky](https://fortran-lang.discourse.group/u/Beliavsky)\
**Post date:** [May 20, 2026, 2:20pm UTC](https://fortran-lang.discourse.group/t/fortitude-0-9-0-release/10900/7 "2026-05-20T14:20:38Z")

</div>

> [@Simo](#):
>
> ` integer :: x(3, 3, 3, 3) ! 4D array`

should be

`integer :: x(3, 3, 1, 1) ! 4D array`

I think.

---

<div class="post-metadata">

**Author:** ![Simo](https://avatars.discourse-cdn.com/v4/letter/s/90db22/32.png) [@Simo](https://fortran-lang.discourse.group/u/Simo)\
**Post date:** [May 20, 2026, 2:26pm UTC](https://fortran-lang.discourse.group/t/fortitude-0-9-0-release/10900/8 "2026-05-20T14:26:52Z")

</div>

```fortran
$ cat main.f90
program demo
  implicit none
  integer :: x(3, 3, 3, 3) ! 4D array

  call fill_as_2d(x)

  print *, "Works."
contains
  subroutine fill_as_2d(a)
    implicit none
    integer, intent(out) :: a(3,3) !!! < redefined as 2D array

    a = 1

  end subroutine fill_as_2d
end program demo

```

```fortran
$ gfortran -Wall -Wextra -Wsurprising -o demo main.f90

```

```fortran
$ ./demo
 Works.

```

---

<div class="post-metadata">

**Author:** ![RonShepard](https://avatars.discourse-cdn.com/v4/letter/r/a3d4f5/32.png) [@RonShepard](https://fortran-lang.discourse.group/u/RonShepard)\
**Post date:** [May 20, 2026, 5:58pm UTC](https://fortran-lang.discourse.group/t/fortitude-0-9-0-release/10900/9 "2026-05-20T17:58:15Z")

</div>

> [@Simo](#):
>
> `call fill_as_2d(x)`

This is the way that line of code would have been written in f77, before array syntax. Nowadays, one would probably write that line of code as

```auto
call fill_as_2d( x(:,:,1,1) )

```

I think this does exactly the same thing, the compiler will see those two lines as being equivalent, but now a human reader will see that only a subset of the array elements are being referenced, and he will also see that a rank-2 actual array argument is associated with a rank-2 dummy array, so everything is now clear.

On the other hand, if the line of code were written as

```auto
call fill_as_2d( x(1,:,1,:)) 

```

then this is still legal fortran, but now the compiler must do something special (e.g. copy-in/copy-out type argument association) to make things work. (actually, only copy-out in this case because of `intent(out)`). This requires slice notation and array syntax, so this was not possible with f77. The programmer must understand the storage sequence convention to know the difference.
