Skip to main content

HYCOM correctness & modernization

Goal

Learn how to use Codee to ensure correctness and modernize HYCOM, an ocean modeling system consisting of dozens of files.

Getting ready

For this demonstration, we will use HYCOM, an ocean modeling system consisting of dozens of files. Start by cloning the repository:

git clone https://github.com/codee-com/codee-demos.git

Walkthrough

1. Generate the compile_commands.json

Firstly, navigate to the source code directory:

cd codee-demos/Fortran/HYCOM/src/

The project comes with a Makefile, so we can leverage the tool bear (version 3 or later) to generate the compile_commands.json file required by Codee:

bear -- make

It is as simple as prepending bear -- to the make invocation. This command will produce a compile_commands.json file with all the compiler invocations needed to build the source files.

2. Run the screening report

New feature

Running codee commands with the additional --db codee.db flag enables Incremental Static Analysis. This reduces runtime by storing analysis results and reusing them in subsequent analysis, reanalyzing only the source code that has changed.

To explore the recommendations of the Open Catalog that are applicable to HYCOM, let's run Codee's screening report; use --compile-commands (or -p as its short version) to point to the compilation database:

Codee command
codee screening --compile-commands compile_commands.json --db codee.db
Codee output
Date: 2026-03-25 Codee version: 2026.1 License type: Trial

Searching Incremental Static Analysis database... Enabled

Dependency processing... Done (5601 ms)

[ 1/50] mod_dimensions.F90 ... Done: new
[ 2/50] mod_xc.F90 ... Done: new
<...>
[36/50] mxkrt.F90 ... Done: new
[37/50] mxkrtm.F90 ... Done: new
[38/50] mxpwp.F90 ... Done: new
[39/50] overtn.F90 ... Done: new
[40/50] poflat.F90 ... Done: new
[41/50] prtmsk.F90 ... Done: new
[42/50] psmoo.F90 ... Done: new
[43/50] thermf.F90 ... Done: new
[44/50] trcupd.F90 ... Done: new
[45/50] machine.F90 ... Done: new
[46/50] wtime.F90 ... Done: new
[47/50] machi_c.c ... Done: new
[48/50] isnan.F90 ... Done: new
[49/50] s8gefs.F90 ... Done: new
[50/50] hycom.F90 ... Done: new

SCREENING REPORT

------Number of files------
Total | C C++ Fortran Other
----- | - --- ------- -----
50 | 1 0 49 0

RANKING OF QUALITY CHECKERS

Checker Category Priority AutoFixes # Title
------- ---------------------------------- -------- --------- ---- ----------------------------------------------------------------------------
PWR068 correctness, modern, security P18 (L1) 192 Call procedures through explicit interfaces, preferably as module procedures
PWR007 correctness, modern, security P18 (L1) 19 22 Disable the implicit declaration of variables and procedures
PWR004 correctness, security P12 (L1) 226 Declare OpenMP scoping for all variables
PWR080 correctness, portability, security P12 (L1) 39 Conditionally initialized variables can lead to undefined behavior
PWR063 correctness, modern, security P12 (L1) 19 Avoid using legacy Fortran constructs
PWR073 correctness, modern, security P12 (L1) 7 Transform common block into a module for better data encapsulation
PWR008 correctness, modern, security P9 (L2) 30 196 Declare the intent for each procedure argument
PWR069 correctness, modern, security P9 (L2) 146 146 Use the keyword only to explicitly state what to import from a module
PWR081 correctness, portability, security P9 (L2) 2 Avoid undefined behavior due to uninitialized output argument
PWR005 correctness, security P8 (L2) 288 Disable default OpenMP scoping
PWR075 modern, portability, security P8 (L2) 20 Avoid using compiler-specific Fortran extensions
PWR071 modern, portability, security P6 (L2) 831 Prefer real(kind=kind_value) for declaring consistent floating types
PWR082 correctness, security P4 (L3) 228 Remove unused variables
PWR001 correctness, modern, security P4 (L3) 189 Pass global variables as function arguments
PWR070 correctness, modern, security P4 (L3) 74 Declare array dummy arguments as assumed-shape arrays
PWR003 modern, security P3 (L3) 7 Explicitly declare pure functions
------- ---------------------------------- -------- --------- ---- ----------------------------------------------------------------------------
Total 195 2486

SUGGESTIONS

Get a breakdown per file of the Screening Report (--verbose), focusing on one specific checker (--check-id), e.g.:
codee screening --verbose --check-id PWR068 --compile-commands compile_commands.json --db codee.db

0 file analyses reused from cache, 50 files analyzed from scratch
50 target files, 251 functions, 2058 loops, 44679 SLOCs successfully analyzed (2486 checkers) and 0 non-analyzed files in 1 m 37 s

3. Re-run the screening report with --verbose

Let's focus the analysis on one of the reported checkers. We can filter Codee's output with the --check-id flag. For example, let's pick PWR008, for which Codee has AutoFixes available. At the same time, let's add the --verbose flag, so we can see the specific list of files where at least one PWR008 was triggered:

Codee command
codee screening --verbose --compile-commands compile_commands.json --check-id PWR008 --db codee.db
Codee output
Date: 2026-03-23 Codee version: 2025.4.9-245 License type: Team

Searching Incremental Static Analysis database... Enabled

Dependency processing... Done (8 ms)

[ 1/50] mod_dimensions.F90 ... Cached
[ 2/50] mod_xc.F90 ... Cached
<...>
[50/50] hycom.F90 ... Cached

SCREENING REPORT

------Number of files------
Total | C C++ Fortran Other
----- | - --- ------- -----
50 | 1 0 49 0

Target # checks Check IDs
----------------------------------------------------------- -------- ----------
/home/user/codee-demos/Fortran/HYCOM/src/forfun.F90 23 PWR008(23)
/home/user/codee-demos/Fortran/HYCOM/src/s8gefs.F90 18 PWR008(18)
/home/user/codee-demos/Fortran/HYCOM/src/hybgen.F90 11 PWR008(11)
/home/user/codee-demos/Fortran/HYCOM/src/mxkprf.F90 11 PWR008(11)
/home/user/codee-demos/Fortran/HYCOM/src/mod_floats.F90 10 PWR008(10)
/home/user/codee-demos/Fortran/HYCOM/src/diapfl.F90 10 PWR008(10)
/home/user/codee-demos/Fortran/HYCOM/src/mod_tides.F90 9 PWR008(9)
/home/user/codee-demos/Fortran/HYCOM/src/mod_incupd.F90 7 PWR008(7)
/home/user/codee-demos/Fortran/HYCOM/src/mod_restart.F90 7 PWR008(7)
/home/user/codee-demos/Fortran/HYCOM/src/mxpwp.F90 7 PWR008(7)
/home/user/codee-demos/Fortran/HYCOM/src/thermf.F90 7 PWR008(7)
/home/user/codee-demos/Fortran/HYCOM/src/trcupd.F90 7 PWR008(7)
/home/user/codee-demos/Fortran/HYCOM/src/mod_momtum.F90 6 PWR008(6)
/home/user/codee-demos/Fortran/HYCOM/src/mxkrt.F90 6 PWR008(6)
/home/user/codee-demos/Fortran/HYCOM/src/blkdat.F90 5 PWR008(5)
/home/user/codee-demos/Fortran/HYCOM/src/inigiss.F90 5 PWR008(5)
/home/user/codee-demos/Fortran/HYCOM/src/mod_mean.F90 4 PWR008(4)
/home/user/codee-demos/Fortran/HYCOM/src/mod_archiv.F90 4 PWR008(4)
/home/user/codee-demos/Fortran/HYCOM/src/psmoo.F90 4 PWR008(4)
/home/user/codee-demos/Fortran/HYCOM/src/mod_stokes.F90 3 PWR008(3)
/home/user/codee-demos/Fortran/HYCOM/src/mod_tsadvc.F90 3 PWR008(3)
/home/user/codee-demos/Fortran/HYCOM/src/bigrid.F90 3 PWR008(3)
/home/user/codee-demos/Fortran/HYCOM/src/latbdy.F90 3 PWR008(3)
/home/user/codee-demos/Fortran/HYCOM/src/matinv.F90 3 PWR008(3)
/home/user/codee-demos/Fortran/HYCOM/src/mxkrtm.F90 3 PWR008(3)
/home/user/codee-demos/Fortran/HYCOM/src/poflat.F90 3 PWR008(3)
/home/user/codee-demos/Fortran/HYCOM/src/mod_dimensions.F90 2 PWR008(2)
/home/user/codee-demos/Fortran/HYCOM/src/mod_asselin.F90 2 PWR008(2)
/home/user/codee-demos/Fortran/HYCOM/src/convec.F90 2 PWR008(2)
/home/user/codee-demos/Fortran/HYCOM/src/mod_barotp.F90 1 PWR008(1)
/home/user/codee-demos/Fortran/HYCOM/src/cnuity.F90 1 PWR008(1)
/home/user/codee-demos/Fortran/HYCOM/src/geopar.F90 1 PWR008(1)
/home/user/codee-demos/Fortran/HYCOM/src/icloan.F90 1 PWR008(1)
/home/user/codee-demos/Fortran/HYCOM/src/inicon.F90 1 PWR008(1)
/home/user/codee-demos/Fortran/HYCOM/src/overtn.F90 1 PWR008(1)
/home/user/codee-demos/Fortran/HYCOM/src/prtmsk.F90 1 PWR008(1)
/home/user/codee-demos/Fortran/HYCOM/src/isnan.F90 1 PWR008(1)
------------------------------------------------------------- -------- ----------
Total 196

Target : analyzed directory or source code file
# checks : total actionable items (opportunities, recommendations, defects and remarks) detected
Check IDs : list of checks reported for the target

RANKING OF QUALITY CHECKERS

Checker Category Priority AutoFixes # Title
------- ----------------------------- -------- --------- --- ----------------------------------------------
PWR008 correctness, modern, security P9 (L2) 30 196 Declare the intent for each procedure argument
------- ----------------------------- -------- --------- --- ----------------------------------------------
Total 30 196

SUGGESTIONS

Run the 'checks' report to list the checkers on screen pinpointing lines of code of a given file:
codee checks /home/user/codee-demos/Fortran/HYCOM/src/forfun.F90 --verbose --compile-commands compile_commands.json --check-id PWR008 --db codee.db

50 file analyses reused from cache, 0 files analyzed from scratch
50 target files, 251 functions, 2058 loops, 44679 SLOCs successfully analyzed (196 checkers) and 0 non-analyzed files in 733 ms

4. Run the checks report

Use Codee's checks report to see the list of checkers reported for the file mod_floats.F90, which in this case was one of the files with the highest number of PWR008 reported. To streamline the demonstration, the analysis will concentrate on the f_stat function, selected for its representative complexity and relevance:

Codee command
codee checks --compile-commands compile_commands.json --check-id PWR008 --verbose mod_floats.F90:f_stat --db codee.db
Codee output
Date: 2026-03-26 Codee version: 2026.1 License type: Team

Searching Incremental Static Analysis database... Enabled

Dependency processing... Done (161 ms)

[Dep] mod_dimensions.F90 ... Cached
[Dep] mod_xc.F90 ... Cached
[Dep] mod_cb_arrays.F90 ... Cached
[Dep] mod_pipe.F90 ... Cached
[1/1] mod_floats.F90 ... Cached

QUALITY CHECKS REPORT

mod_floats.F90:2607:7 [PWR008] (level: L2): Declare the intent for each procedure argument
Suggestion: Add the missing INTENT for arguments of the procedure 'f_stat':
intent in: 'ser' and 'ls'
intent out*: 'std'
intent inout*: 'amean' and 'var'
* May break compilation if literal values are used for these arguments in calls to 'f_stat'; only variables may be used
Documentation:
https://open-catalog.codee.com/Checks/PWR008
AutoFix:
codee rewrite --check-id pwr008 --in-place mod_floats.F90:f_stat --compile-commands compile_commands.json --db codee.db

5 file analyses reused from cache, 0 files analyzed from scratch
1 target file, 1 function, 2 loops, 2028 SLOCs successfully analyzed (1 checker) and 0 non-analyzed files in 234 ms

Codee offers an AutoFix for this checker, just copy and paste the suggested codee rewrite command to apply it.

5. Autofix

Let's use Codee's autofix capabilities to automatically modernize the code:

Codee command
codee rewrite --check-id pwr008 --in-place mod_floats.F90:f_stat --compile-commands compile_commands.json --db codee.db
Codee output
Date: 2026-03-26 Codee version: 2026.1 License type: Team

Searching Incremental Static Analysis database... Enabled

Dependency processing... Done (158 ms)

[Dep] mod_dimensions.F90 ... Done
[Dep] mod_xc.F90 ... Done
[Dep] mod_cb_arrays.F90 ... Done
[Dep] mod_pipe.F90 ... Done
[1/1] mod_floats.F90 ... Done

Results for file '/home/user/codee-demos/Fortran/HYCOM/src/mod_floats.F90':
Successfully applied AutoFix to the procedure at 'mod_floats.F90:2607:7' [using insert argument intent]

Successfully updated /home/user/codee-demos/Fortran/HYCOM/src/mod_floats.F90

We can review the code changes to verify correctness:

diff command
git diff .
diff output
diff --git a/Fortran/HYCOM/src/mod_floats.F90 b/Fortran/HYCOM/src/mod_floats.F90
index d1d2581..4f3beee 100644
--- a/Fortran/HYCOM/src/mod_floats.F90
+++ b/Fortran/HYCOM/src/mod_floats.F90
@@ -2608,8 +2608,10 @@
implicit none
!
! --- computes mean, variance, standard deviation of data sequence
- real, dimension(16) :: ser
- integer ls
+ ! Codee: Added argument intent (2025-11-06 12:01:26)
+ real, dimension(16), intent(in) :: ser
+ ! Codee: Added argument intent (2025-11-06 12:01:26)
+ integer, intent(in) :: ls
real amean,var,std
real sum,value
integer j