Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Benchmark/src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,5 @@ endif()
add_benchmark(PWR079)
add_benchmark(PWR080)
add_benchmark(PWR081)
add_benchmark(PWR082)
add_benchmark(PWR083)
66 changes: 66 additions & 0 deletions Benchmark/src/PWR082.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#include "Benchmark.h"

// Forward-declare the functions to benchmark
extern "C" {
double sum_array(const int n, const double *array);
double sum_array_improved(const int n, const double *array);
double sum_array_f(const int n, const double *array);
double sum_array_improved_f(const int n, const double *array);
}

// Size adjusted to fit execution on micro-seconds
constexpr int N = 1024 * 1024;

#if OCB_ENABLE_C

static void CExampleBench(benchmark::State &state) {
auto array = OpenCatalog::CreateRandomVector<double>(N);

for (auto _ : state) {
double result = sum_array(N, array.data());
benchmark::DoNotOptimize(result);
}
}

static void CImprovedBench(benchmark::State &state) {
auto array = OpenCatalog::CreateRandomVector<double>(N);

for (auto _ : state) {
double result = sum_array_improved(N, array.data());
benchmark::DoNotOptimize(result);
}
}

// The goal of these benchmarks is to demonstrate that the suggested check does
// not incur any performance penalty
OC_BENCHMARK("PWR082 C Example", CExampleBench);
OC_BENCHMARK("PWR082 C Improved", CImprovedBench);

#endif

#if OCB_ENABLE_Fortran

static void FortranExampleBench(benchmark::State &state) {
auto array = OpenCatalog::CreateRandomVector<double>(N);

for (auto _ : state) {
double result = sum_array_f(N, array.data());
benchmark::DoNotOptimize(result);
}
}

static void FortranImprovedBench(benchmark::State &state) {
auto array = OpenCatalog::CreateRandomVector<double>(N);

for (auto _ : state) {
double result = sum_array_improved_f(N, array.data());
benchmark::DoNotOptimize(result);
}
}

// The goal of these benchmarks is to demonstrate that the suggested check does
// not incur any performance penalty
OC_BENCHMARK("PWR082 Fortran Example", FortranExampleBench);
OC_BENCHMARK("PWR082 Fortran Improved", FortranImprovedBench);

#endif
132 changes: 132 additions & 0 deletions Checks/PWR082/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
# PWR082: Remove unused variables

### Issue

A variable that is declared but never used adds noise: it increases the amount
of information to keep track of, suggesting data flow that does not actually
exist. In some cases, an unused variable may instead hint at a hidden defect in
the program's logic, such as a missing assignment or an incomplete computation.

### Actions

Determine whether each unused variable is accidentally or intentionally unused;
remove those that are not needed. If a variable is intentionally unused but,
for any reason, it cannot be removed, make that intent explicit using
language-specific mechanisms.

### Relevance

Fortran, C, and C++ allow variables to be declared without ever being used.
Eliminating unused variables reduces cognitive load and avoids suggesting
nonexistent data flow, helping readers focus on what actually contributes to
the program's behavior.

If a variable `x` must remain intentionally unused (e.g., an argument required
in an API call but unused in a particular implementation), it is possible to
document that intent using language constructs, such as:

- **C:** `[[maybe_unused]] int x` (since C23), or compiler-specific annotations
such as `gcc`'s `__attribute__((unused))`. Another common alternative,
although less explicit, is to "consume" the variable with a cast `(void) x`.

- **C++:** `[[maybe_unused]] int x` (since C++17).

- **Fortran:** There is no standard attribute, and compilers such as `gfortran`
do not provide attributes for annotation. A simple and portable approach is
to create a reference with no runtime effect:

```fortran
associate(unused => x)
end associate
```

### Code examples

#### C

In the following code, the variable `t` is declared but never used to perform
the computation:

```c {3} showLineNumbers
// example.c
__attribute__((pure)) int sumArray(const int n, const int *array) {
int t, sum = 0;

for (int i = 0; i < n; ++i) {
sum += array[i];
}

return sum;
}
```

Thus, `t` should be removed:

```c {3} showLineNumbers
// solution.c
__attribute__((pure)) int sumArray(const int n, const int *array) {
int sum = 0;

for (int i = 0; i < n; ++i) {
sum += array[i];
}

return sum;
}
```

#### Fortran

In the following code, the variable `t` is declared but never used to perform
the computation:

```fortran {5} showLineNumbers
! example.f90
pure function sumArray(array) result(sum)
implicit none
integer, intent(in) :: array(:)
integer :: t, sum, i

sum = 0

do i = 1, size(array)
sum = sum + array(i)
end do
end function sumArray
```

Thus, `t` should be removed:

```fortran {5} showLineNumbers
! solution.f90
pure function sumArray(array) result(sum)
implicit none
integer, intent(in) :: array(:)
integer :: sum, i

sum = 0

do i = 1, size(array)
sum = sum + array(i)
end do
end function sumArray
```

### Related resources

- [PWR082
examples](https://github.com/codee-com/open-catalog/tree/main/Checks/PWR082/)

### References

- ["Common Variable Attributes (Using the GNU Compiler Collection
(GCC))"](https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-unused-variable-attribute),
Free Software Foundation, Inc. [last checked February 2026]

- ["C attribute: maybe_unused (since
C23)"](https://en.cppreference.com/w/c/language/attributes/maybe_unused.html),
cppreference.com. [last checked February 2026]

- ["C++ attribute: maybe_unused (since
C++17)"](https://en.cppreference.com/w/cpp/language/attributes/maybe_unused.html),
cppreference.com. [last checked February 2026]
11 changes: 11 additions & 0 deletions Checks/PWR082/benchmark/example.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// PWR082: Remove unused variables

__attribute__((pure)) double sum_array(const int n, const double *array) {
double t, sum = 0.0;

for (int i = 0; i < n; ++i) {
sum += array[i];
}

return sum;
}
18 changes: 18 additions & 0 deletions Checks/PWR082/benchmark/example.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
! PWR082: Remove unused variables

! NOT-PWR070: Explicit-shape arrays used for C-interoperability
pure function sum_array_f(n, array) result(sum) bind(c)
use iso_c_binding, only: c_double, c_int
implicit none

integer(kind=c_int), intent(in), value :: n
real(kind=c_double), dimension(n), intent(in) :: array
real(kind=c_double) :: t, sum
integer(kind=c_int) :: i

sum = 0

do i = 1, n
sum = sum + array(i)
end do
end function sum_array_f
12 changes: 12 additions & 0 deletions Checks/PWR082/benchmark/solution.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// PWR082: Remove unused variables

__attribute__((pure)) double sum_array_improved(const int n,
const double *array) {
double sum = 0.0;

for (int i = 0; i < n; ++i) {
sum += array[i];
}

return sum;
}
18 changes: 18 additions & 0 deletions Checks/PWR082/benchmark/solution.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
! PWR082: Remove unused variables

! NOT-PWR070: Explicit-shape arrays used for C-interoperability
pure function sum_array_improved_f(n, array) result(sum) bind(c)
use iso_c_binding, only: c_double, c_int
implicit none

integer(kind=c_int), intent(in), value :: n
real(kind=c_double), dimension(n), intent(in) :: array
real(kind=c_double) :: sum
integer(kind=c_int) :: i

sum = 0

do i = 1, n
sum = sum + array(i)
end do
end function sum_array_improved_f
11 changes: 11 additions & 0 deletions Checks/PWR082/example.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// PWR082: Remove unused variables

__attribute__((pure)) int sumArray(const int n, const int *array) {
int t, sum = 0;

for (int i = 0; i < n; ++i) {
sum += array[i];
}

return sum;
}
13 changes: 13 additions & 0 deletions Checks/PWR082/example.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
! PWR082: Remove unused variables

pure function sumArray(array) result(sum)
implicit none
integer, intent(in) :: array(:)
integer :: t, sum, i

sum = 0

do i = 1, size(array)
sum = sum + array(i)
end do
end function sumArray
11 changes: 11 additions & 0 deletions Checks/PWR082/solution.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// PWR082: Remove unused variables

__attribute__((pure)) int sumArray(const int n, const int *array) {
int sum = 0;

for (int i = 0; i < n; ++i) {
sum += array[i];
}

return sum;
}
13 changes: 13 additions & 0 deletions Checks/PWR082/solution.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
! PWR082: Remove unused variables

pure function sumArray(array) result(sum)
implicit none
integer, intent(in) :: array(:)
integer :: sum, i

sum = 0

do i = 1, size(array)
sum = sum + array(i)
end do
end function sumArray
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ designed to demonstrate:
| [PWR079](Checks/PWR079/) | Avoid undefined behavior due to uninitialized variables | correctness, portability, security | [CWE-758](https://cwe.mitre.org/data/definitions/758.html), [CWE-908](https://cwe.mitre.org/data/definitions/908.html), [CWE-909](https://cwe.mitre.org/data/definitions/909.html) | [6.13](https://j3-fortran.org/doc/year/23/23-241.pdf), [6.22](https://j3-fortran.org/doc/year/23/23-241.pdf), [6.56](https://j3-fortran.org/doc/year/23/23-241.pdf) | [EXP33-C](https://wiki.sei.cmu.edu/confluence/display/c/EXP33-C.+Do+not+read+uninitialized+memory), [EXP34-C](https://wiki.sei.cmu.edu/confluence/display/c/EXP34-C.+Do+not+dereference+null+pointers), [MSC15-C](https://wiki.sei.cmu.edu/confluence/display/c/MSC15-C.+Do+not+depend+on+undefined+behavior) | [EXP53-CPP](https://wiki.sei.cmu.edu/confluence/spaces/cplusplus/pages/88046609/EXP53-CPP.+Do+not+read+uninitialized+memory) | ✓ | ✓ | ✓ | |
| [PWR080](Checks/PWR080/) | Conditionally initialized variables can lead to undefined behavior | correctness, portability, security | [CWE-758](https://cwe.mitre.org/data/definitions/758.html), [CWE-908](https://cwe.mitre.org/data/definitions/908.html), [CWE-909](https://cwe.mitre.org/data/definitions/909.html) | [6.13](https://j3-fortran.org/doc/year/23/23-241.pdf), [6.22](https://j3-fortran.org/doc/year/23/23-241.pdf), [6.56](https://j3-fortran.org/doc/year/23/23-241.pdf) | [EXP33-C](https://wiki.sei.cmu.edu/confluence/display/c/EXP33-C.+Do+not+read+uninitialized+memory), [EXP34-C](https://wiki.sei.cmu.edu/confluence/display/c/EXP34-C.+Do+not+dereference+null+pointers), [MSC15-C](https://wiki.sei.cmu.edu/confluence/display/c/MSC15-C.+Do+not+depend+on+undefined+behavior) | [EXP53-CPP](https://wiki.sei.cmu.edu/confluence/spaces/cplusplus/pages/88046609/EXP53-CPP.+Do+not+read+uninitialized+memory) | ✓ | ✓ | ✓ | |
| [PWR081](Checks/PWR081/) | Uninitialized output arguments can lead to undefined behavior | correctness, portability, security | [CWE-758](https://cwe.mitre.org/data/definitions/758.html), [CWE-908](https://cwe.mitre.org/data/definitions/908.html), [CWE-909](https://cwe.mitre.org/data/definitions/909.html) | [6.13](https://j3-fortran.org/doc/year/23/23-241.pdf), [6.22](https://j3-fortran.org/doc/year/23/23-241.pdf), [6.56](https://j3-fortran.org/doc/year/23/23-241.pdf) | [EXP33-C](https://wiki.sei.cmu.edu/confluence/display/c/EXP33-C.+Do+not+read+uninitialized+memory), [EXP34-C](https://wiki.sei.cmu.edu/confluence/display/c/EXP34-C.+Do+not+dereference+null+pointers), [MSC15-C](https://wiki.sei.cmu.edu/confluence/display/c/MSC15-C.+Do+not+depend+on+undefined+behavior) | | | ✓ | | |
| [PWR082](Checks/PWR082/) | Remove unused variables | correctness, security | [CWE-563](https://cwe.mitre.org/data/definitions/563.html) | [6.19](https://j3-fortran.org/doc/year/23/23-241.pdf) | [MSC13-C](https://wiki.sei.cmu.edu/confluence/spaces/c/pages/87152095/MSC13-C.+Detect+and+remove+unused+values) | | ✓ | ✓ | ✓ | |
| [PWR083](Checks/PWR083/) | Match the types of dummy and actual arguments in procedure calls | correctness, security | [CWE-628](https://cwe.mitre.org/data/definitions/628.html), [CWE-758](https://cwe.mitre.org/data/definitions/758.html) | [6.11](https://j3-fortran.org/doc/year/23/23-241.pdf), [6.32](https://j3-fortran.org/doc/year/23/23-241.pdf), [6.53](https://j3-fortran.org/doc/year/23/23-241.pdf), [6.56](https://j3-fortran.org/doc/year/23/23-241.pdf) | [EXP37-C](https://wiki.sei.cmu.edu/confluence/display/c/EXP37-C.+Call+functions+with+the+correct+number+and+type+of+arguments), [MSC15-C](https://wiki.sei.cmu.edu/confluence/display/c/MSC15-C.+Do+not+depend+on+undefined+behavior) | | | ✓ | | |
| [PWR088](Checks/PWR088/) | Add missing arguments to procedure calls | correctness, security | [CWE-628](https://cwe.mitre.org/data/definitions/628.html), [CWE-758](https://cwe.mitre.org/data/definitions/758.html) | [6.32](https://j3-fortran.org/doc/year/23/23-241.pdf), [6.56](https://j3-fortran.org/doc/year/23/23-241.pdf) | [EXP37-C](https://wiki.sei.cmu.edu/confluence/display/c/EXP37-C.+Call+functions+with+the+correct+number+and+type+of+arguments), [MSC15-C](https://wiki.sei.cmu.edu/confluence/display/c/MSC15-C.+Do+not+depend+on+undefined+behavior) | | | ✓ | | |
| [PWR089](Checks/PWR089/) | Remove unexpected arguments from procedure calls | correctness, security | [CWE-628](https://cwe.mitre.org/data/definitions/628.html), [CWE-758](https://cwe.mitre.org/data/definitions/758.html) | [6.32](https://j3-fortran.org/doc/year/23/23-241.pdf), [6.56](https://j3-fortran.org/doc/year/23/23-241.pdf) | [EXP37-C](https://wiki.sei.cmu.edu/confluence/display/c/EXP37-C.+Call+functions+with+the+correct+number+and+type+of+arguments), [MSC15-C](https://wiki.sei.cmu.edu/confluence/display/c/MSC15-C.+Do+not+depend+on+undefined+behavior) | | | ✓ | | |
Expand Down