HYCOM correctness & modernization
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
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 screening --compile-commands compile_commands.json
Date: 2025-11-06 Codee version: 2025.4 License type: Trial
Dependency processing... Done (2632 ms)
[ 1/50] mod_dimensions.F90 ... Done
[ 2/50] mod_xc.F90 ... Done
<...>
[50/50] hycom.F90 ... Done
SCREENING REPORT
------Number of files------
Total | C C++ Fortran Other
----- | - --- ------- -----
50 | 1 0 49 0
RANKING OF QUALITY CHECKERS
Checker Category Priority AutoFixes # Title
------- ------------------------------------- -------- --------- ---- ---------------------------------------------------------------------------------------
PWR075 modern, portability, security P12 (L1) 20 Avoid using compiler-specific Fortran extensions
PWR063 correctness, modern, security P12 (L1) 19 Avoid using legacy Fortran constructs
PWR008 correctness, modern, security P9 (L2) 16 196 Declare the intent for each procedure argument
PWR068 correctness, modern, security P9 (L2) 192 Encapsulate procedures within modules to avoid the risks of calling implicit interfaces
PWR069 correctness, modern, security P9 (L2) 146 146 Use the keyword only to explicitly state what to import from a module
PWR007 correctness, modern, security P9 (L2) 19 22 Disable the implicit declaration of variables and procedures
PWR004 correctness P6 (L2) 226 Declare OpenMP scoping for all variables
PWR003 modern, security, other P6 (L2) 7 Explicitly declare pure functions
PWR071 modern, portability, security P3 (L3) 831 Prefer real(kind=kind_value) for declaring consistent floating types
PWR005 correctness P3 (L3) 288 Disable default OpenMP scoping
PWR073 correctness, modern, security P3 (L3) 5 Transform common block into a module for better data encapsulation
PWR070 correctness, modern, security, memory P2 (L3) 74 Declare array dummy arguments as assumed-shape arrays
PWR001 correctness, modern, security P1 (L3) 189 Pass global variables as function arguments
------- ------------------------------------- -------- --------- ---- ---------------------------------------------------------------------------------------
Total 181 2215
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 PWR075 --compile-commands compile_commands.json
Take advantage of static incremental analysis by specifying both a database (--db) and a target source file, e.g.:
codee screening --db codee.db mod_dimensions.F90 --compile-commands compile_commands.json
50 target files, 251 functions, 2058 loops, 44679 LOCs successfully analyzed (2215 checkers) and 0 non-analyzed files in 1 m 6 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 screening --verbose --compile-commands compile_commands.json --check-id PWR008
Date: 2025-11-06 Codee version: 2025.4 License type: Trial
Dependency processing... Done (2608 ms)
[ 1/50] mod_dimensions.F90 ... Done
[ 2/50] mod_xc.F90 ... Done
<...>
[50/50] hycom.F90 ... Done
SCREENING REPORT
------Number of files------
Total | C C++ Fortran Other
----- | - --- ------- -----
50 | 1 0 49 0
Target # checks Check IDs
-------------- -------- --------------
forfun.F90 23 PWR008(23)
s8gefs.F90 18 PWR008(18)
hybgen.F90 11 PWR008(11)
mxkprf.F90 11 PWR008(11)
mod_floats.F90 10 PWR008(10)
<...>
-------------- -------- ---------------
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) 16 196 Declare the intent for each procedure argument
------- ----------------------------- -------- --------- --- ----------------------------------------------
Total 16 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
Take advantage of static incremental analysis by specifying both a database (--db) and a target source file, e.g.:
codee screening --db codee.db mod_dimensions.F90 --verbose --compile-commands compile_commands.json --check-id PWR008
50 target files, 251 functions, 2058 loops, 44679 LOCs successfully analyzed (196 checkers) and 0 non-analyzed files in 1 m 0 s
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 checks --compile-commands compile_commands.json --check-id PWR008 --verbose mod_floats.F90:f_stat
Date: 2025-11-06 Codee version: 2025.4 License type: Trial
Dependency processing... Done (2599 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
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
SUGGESTIONS
Take advantage of static incremental analysis by specifying both a database (--db) and a target source file, e.g.:
codee checks --db codee.db mod_floats.F90 --compile-commands compile_commands.json --check-id PWR008 --verbose mod_floats.F90:f_stat
1 target file, 1 function, 2 loops, 2028 LOCs successfully analyzed (1 checker) and 0 non-analyzed files in 5227 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 rewrite --check-id pwr008 --in-place mod_floats.F90:f_stat --compile-commands compile_commands.json
Date: 2025-11-06 Codee version: 2025.4 License type: Trial
Dependency processing... Done (2630 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 'mod_floats.F90':
Successfully applied AutoFix to the procedure at 'mod_floats.F90:2607:7' [using insert argument intent]
Successfully updated mod_floats.F90
We can review the code changes to verify correctness:
git diff .
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