Skip to content

Lint Rules ​

fobis lint has 105 rules. Rules marked default run unless a selection is given; opt-in rules run only when selected (--select COR003, a prefix like --select COR, or ALL). Run fobis lint --explain <ID> for the same documentation in the terminal. How to run, select and suppress rules: Code quality.

Correctness (COR) ​

RuleNameSeverityDefaultFortitudeReports
COR001implicit-typingwarningyesC001A module, program or external procedure has no implicit none.
COR002interface-implicit-typingwarningyesC002An interface body has no implicit none.
COR003implicit-external-procedureswarningopt-inC003implicit none does not forbid implicit external procedures (implicit none (type, external)).
COR010missing-intentwarningyesC061A dummy argument has no intent.
COR011assumed-sizewarningyesC071A dummy array is assumed-size (a(*), a(n,*)).
COR020initialisation-in-declarationwarningyesC081A procedure's local variable is initialised in its declaration, which implies save.
COR021pointer-initialisation-in-declarationwarningyesC082A procedure's local pointer is initialised in its declaration (=> null()), which implies save.
COR022missing-default-pointer-initialisationwarningyesC101A pointer component of a derived type has no default initialisation (=> null()).
COR030external-procedurewarningyesC091A procedure is declared external.
COR031procedure-not-in-modulewarningyesC092A subroutine or function is defined outside a module (an external procedure).
COR040use-allwarningyesC121A use statement imports everything (no only: list).
COR041missing-intrinsicwarningyesC122An intrinsic module is used without the intrinsic keyword.
COR050missing-accessibility-statementwarningyesC131A module has no default accessibility statement (private or public).
COR060unchecked-statwarningyesC181The stat= variable of an allocate/deallocate is never read afterwards.
COR061multiple-allocations-with-statwarningyesC182One allocate/deallocate with stat= handles several objects.
COR062stat-without-errmsgwarningopt-inC183An allocate/deallocate has stat= but no errmsg=.
COR070missing-default-casewarningyesC011A select case construct has no case default.
COR071missing-class-defaultwarningopt-in-A select type construct has no class default.
COR072missing-rank-defaultwarningopt-in-A select rank construct has no rank default.
COR080magic-number-in-array-sizewarningopt-inC031An array is declared with a literal size other than 0 or 1.
COR081magic-io-unitwarningopt-inC032An I/O statement uses a literal unit number.
COR082missing-action-specifierwarningopt-inC043An open statement has no action= specifier.
COR090missing-exit-or-cycle-labelwarningyesC141An exit or cycle inside a named DO loop does not name the loop.
COR091exit-or-cycle-in-unlabelled-loopwarningopt-inC142An exit or cycle appears in a DO loop that has no construct name.
COR092missing-end-labelerroryesC143The end statement of a named construct does not repeat the construct name.
COR100misleading-inline-if-semicolonwarningyesC151A statement follows a one-line if after a semicolon: it is not conditional.
COR101misleading-inline-if-continuationwarningyesC152A one-line if continues its action on the next line.
COR110nonportable-shortcircuit-inquirywarningyesC161A condition tests present/allocated/associated and uses the same entity in one expression.
COR120unreachable-statementwarningyesC191A statement follows return, stop, exit, cycle or go to in the same block: it never runs.

Obsolescent (OBS) ​

RuleNameSeverityDefaultFortitudeReports
OBS001common-blockwarningyesOB011A common block.
OBS002equivalence-statementwarningyesOB012An equivalence statement.
OBS003block-datawarningyesOB013A block data program unit.
OBS004entry-statementwarningyesOB021An entry statement.
OBS005specific-intrinsic-namewarningyesOB031A specific intrinsic name (dsqrt, dabs, amax1, float ...) instead of the generic one.
OBS006computed-go-towarningyesOB041A computed go to (l1, l2, ...), i.
OBS007pause-statementwarningyesOB051A pause statement.
OBS008deprecated-character-syntaxwarningyesOB061Old-style character length character*n / character*(*).
OBS009forallwarningyesOB071A forall statement or construct.
OBS010arithmetic-ifwarningyesOB081An arithmetic if (x) l1, l2, l3.
OBS011labelled-do-loopwarningyesOB091A labelled do 10 i = ... loop.
OBS012shared-do-terminationwarningyesOB092Several do loops end on the same labelled statement.
OBS013bad-do-terminationwarningyesOB093A labelled do loop ends on a statement other than continue or end do.
OBS014goto-end-dowarningyesOB094A go to jumps to the end do of a loop.
OBS020deprecated-mpi-includewarningyesOB201include 'mpif.h' instead of the mpi_f08 module.
OBS021deprecated-omp-includewarningyesOB211include 'omp_lib.h' instead of the omp_lib module.

Modernisation (MDN) ​

RuleNameSeverityDefaultFortitudeReports
MDN001double-precisionwarningopt-inMOD001A double precision (or double complex) declaration.
MDN002double-precision-literalwarningopt-inMOD002A double precision literal with exponent letter d (1.0d0).
MDN011old-style-array-constructorwarningyesMOD011An array constructor written (/ ... /) instead of [ ... ].
MDN021deprecated-relational-operatorwarningyesMOD021A relational operator written .eq., .ne., .lt., .le., .gt., .ge..
MDN031include-statementwarningopt-inMOD031A Fortran include line.
MDN041out-of-line-attributewarningyesMOD041An attribute given in a separate statement (dimension a(n), intent(in) :: x, parameter (...)).
MDN051superfluous-savewarningyesMOD051save in a module specification part.
MDN201old-mpi-modulewarningopt-inMOD201use mpi instead of use mpi_f08.

Portability (PRT) ​

RuleNameSeverityDefaultFortitudeReports
PRT011literal-kindwarningyesPORT011A kind given as a number in a type declaration (real(8), integer(kind=4)).
PRT012literal-kind-suffixwarningyesPORT012A literal with a numeric kind suffix (1.0_8, 10_4).
PRT021star-kindwarningyesPORT021A non-standard type*size declaration (real*8, integer*4).
PRT031invalid-tabwarningyesPORT031Tab characters in Fortran code (reported once per file).
PRT061non-portable-system-callwarningopt-inPORT061system() (a compiler extension) runs a shell command.
PRT062gfortran-random-extensionwarningopt-inPORT062The extensions rand, srand, irand generate random numbers.

Style (STY) ​

RuleNameSeverityDefaultFortitudeReports
STY001multiple-moduleswarningopt-inS211A file defines more than one module or submodule.
STY002program-with-modulewarningopt-inS212A file defines both a program and a module.
STY003function-missing-resultwarningopt-inS221A function has no result(...) clause.
STY010inconsistent-array-declarationwarningyesS261A declaration has a dimension attribute and an entity with its own shape.
STY011mixed-scalar-array-declarationwarningopt-inS262One declaration statement declares both scalars and arrays.
STY020too-complexwarningopt-inS901A procedure's cyclomatic complexity exceeds 10.
STY021too-many-argumentswarningopt-inS902A procedure has more than 8 dummy arguments.

Fortran practice (FOR) ​

RuleNameSeverityDefaultFortitudeReports
FOR001saved-local-in-parallel-procedurewarningyes-A procedure that runs in parallel has a saved local variable (one copy shared by all threads).
FOR002loop-order-not-column-majorwarningopt-in-The innermost loop runs over a non-leading array dimension while an outer loop runs over the leading one.
FOR003lower-bounds-lost-in-assumed-shapewarningopt-in-An array with non-default lower bounds is passed to an assumed-shape dummy: inside, its bounds restart at 1.
FOR004function-result-componenterroryes-A component of a function result is referenced directly: f(x)%c.
FOR005cpu-time-for-wall-clockwarningyes-cpu_time measures time in code that runs in parallel (OpenMP, OpenACC, MPI).
FOR006array-of-finalizable-type-not-finalisedwarningyes-An array of a derived type with final procedures, none of which finalises arrays of that rank.
FOR007default-real-literal-precision-losswarningyes-A real literal without kind is assigned to a higher-precision real and cannot be represented in default precision.

OpenMP (OMP) ​

RuleNameSeverityDefaultFortitudeReports
OMP001shared-scalar-written-in-parallel-regionwarningyes-A shared scalar is assigned inside an OpenMP parallel region: a data race.
OMP002accumulation-without-reductionwarningyes-A shared scalar is accumulated inside an OpenMP parallel region without reduction.
OMP003collapse-imperfect-nesterroryes-collapse(n) on OpenMP loops that are not tightly nested.
OMP004nowait-dependent-readwarningopt-in-Data written by a nowait worksharing construct is read before the next barrier.
OMP005serialisation-in-innermost-loopwarningyes-An OpenMP critical or atomic is inside the innermost loop of a parallel loop.
OMP006target-map-in-loopwarningopt-in-An OpenMP target region inside a loop maps data on every iteration, with no target data around it.
OMP007mpi-in-threaded-region-without-thread-supportwarningyes-MPI is called inside an OpenMP parallel region but initialised with mpi_init, not mpi_init_thread.
OMP008implicit-target-mapwarningyes-The compiler maps data implicitly for an OpenMP target region (nvfortran: 'Generating implicit map').

OpenACC (ACC) ​

RuleNameSeverityDefaultFortitudeReports
ACC001implicit-data-movementwarningyes-The compiler moves data implicitly for an OpenACC compute region (nvfortran: 'Generating implicit copy').
ACC002atomic-in-compute-regionwarningyes-An !$acc atomic inside an OpenACC compute region or device routine.
ACC003firstprivate-associate-namewarningyes-An associate name appears in an OpenACC firstprivate clause.
ACC004reduction-into-device-module-variableerroryes-An OpenACC reduction targets a module allocatable declared !$acc declare create.
ACC005strided-section-argument-in-kernelwarningyes-A non-contiguous section of a shared array is passed to a procedure inside OpenACC device code.
ACC006missing-acc-routinewarningyes-A project procedure is called inside an OpenACC compute region but has no !$acc routine.
ACC007device-routine-assumed-shape-lower-boundwarningopt-in-A device routine has an assumed-shape dummy with a non-default lower bound (q(0:), q(1-ng:)).
ACC008timer-without-acc-waitwarningyes-A timer is read while asynchronous OpenACC work may still be running.
ACC009mpi-on-device-data-without-updatewarningopt-in-MPI sends or receives a device-resident array with no host update around the call and no host_data.
ACC010private-array-in-contained-kernelinfoopt-in-A compute region of a contained (internal) procedure has a private array.
ACC011acc-collapse-imperfect-nesterroryes-collapse(n) on OpenACC loops that are not tightly nested.
ACC012sequential-device-loopwarningyes-A loop in an OpenACC compute region runs sequentially: the compiler found a loop-carried dependence.

MPI (MPI) ​

RuleNameSeverityDefaultFortitudeReports
MPI001request-never-completedwarningyes-A non-blocking MPI operation stores its request in a local variable that is never completed.
MPI002isend-buffer-modified-before-completionwarningyes-The buffer of a pending mpi_isend is written before the request is completed.
MPI003irecv-buffer-used-before-completionwarningyes-The buffer of a pending mpi_irecv is used before the request is completed.
MPI004collective-in-rank-branchwarningyes-An MPI collective is called inside a branch that depends on the rank.
MPI005blocking-send-before-receivewarningopt-in-Every rank does a blocking mpi_send and then the matching mpi_recv: a deadlock for large messages.
MPI006any-source-order-dependent-suminfoopt-in-Messages received from MPI_ANY_SOURCE are summed in arrival order: the result is not reproducible.

Performance (PRF) ​

RuleNameSeverityDefaultFortitudeReports
PRF001loop-not-vectorizedinfoopt-in-gfortran could not vectorise a loop (-fopt-info-vec-missed).

Numerics (NUM) ​

RuleNameSeverityDefaultFortitudeReports
NUM001uncompensated-global-suminfoopt-in-A diagnostic quantity (residual, norm, mass, energy ...) is summed across ranks with MPI_SUM.

Linter (LNT) ​

RuleNameSeverityDefaultFortitudeReports
LNT001suppression-without-reasonwarningyes-An inline suppression ! fobis: ignore[ID] gives no reason.
LNT002unused-suppressionwarningyes-An inline suppression silences nothing.
LNT003unknown-rule-in-suppressionwarningyes-An inline suppression names a rule that does not exist.
LNT004preprocessor-assumptioninfoyes-A preprocessor condition could not be evaluated and was assumed true.

Relation to Fortitude ​

The generic rules (COR, OBS, MDN, PRT, STY) are a native reimplementation, in FoBiS's own words and on its own source analysis, of rules catalogued by Fortitude (PlasmaFAIR, MIT licence), whose rule set served as the reference. The Fortitude column gives the matching Fortitude code, for users who know it. FoBiS does not depend on Fortitude. The FOR, NUM, OMP, ACC, MPI and PRF rules are FoBiS's own, distilled from the OpenMP, OpenACC and MPI specifications and from HPC practice.

Not reimplemented: Fortitude's formatting rules (line length, whitespace, keyword case, quotes: formatters own them) and S263 (a project-configured preference between dimension(n) and x(n)). The thresholds of STY020 and STY021 are fixed (complexity 10, 8 arguments).