Skip to content

Commit 5fd0e6c

Browse files
authored
y2038: eliminate false positives with automatic build system detection (danmar#7631)
The Y2038 addon currently generates false positive warnings when scanning codebases that are properly configured for Y2038 safety through build system flags, making it impractical for comprehensive codebase analysis. This prevents teams from running Y2038 checks across entire projects in CI/CD pipelines due to noise from correctly configured code. Add automatic build system detection to discover Y2038-related compiler flags (_TIME_BITS=64, _FILE_OFFSET_BITS=64, _USE_TIME_BITS64) from: - Makefile variants (Makefile, makefile, GNUmakefile, *.mk) - CMake files (CMakeLists.txt, *.cmake) - Meson build files (meson.build) - Autotools scripts (configure, configure.ac, configure.in) - Compiler flags passed via cppcheck -D options When proper Y2038 configuration is detected (both _TIME_BITS=64 AND _FILE_OFFSET_BITS=64), suppress Y2038 warnings and display an informational message indicating the configuration source. Implement hierarchical directory search up to 5 levels from source files to locate relevant build files, with flag precedence: build system > compiler flags > source code #define directives. Add performance optimizations: - Intelligent file caching with TTL-based invalidation - UTF-8 BOM handling for cross-platform compatibility - Robust import fallback system Extend test suite with comprehensive coverage: - Compiler flag parsing edge cases (18 test scenarios) - Build system detection for all supported formats - Caching behavior and performance validation - Cross-platform file encoding handling This enables organizations to run comprehensive Y2038 analysis on entire codebases without false positives from properly configured projects, while maintaining detection of actual Y2038 safety issues.
1 parent 10cdb3d commit 5fd0e6c

File tree

10 files changed

+684
-181
lines changed

10 files changed

+684
-181
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
*.bak
22
*.gcno
3+
*.gch
34
*.o
45
*.pyc
56
/cppcheck

AUTHORS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,7 @@ Ludvig Gunne Lindström
243243
Luis Díaz Más
244244
Luís Pereira
245245
Lukas Grützmacher
246+
Lukas Hiesmayr
246247
Lukasz Czajczyk
247248
Łukasz Jankowski
248249
Luxon Jean-Pierre

addons/README.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ Addons are scripts that analyses Cppcheck dump files to check compatibility with
77
+ [misra.py](https://github.com/danmar/cppcheck/blob/main/addons/misra.py)
88
Used to verify compliance with MISRA C 2012 - a proprietary set of guidelines to avoid such questionable code, developed for embedded systems. Since this standard is proprietary, cppcheck does not display error text by specifying only the number of violated rules (for example, [c2012-21.3]). If you want to display full texts for violated rules, you will need to create a text file containing MISRA rules, which you will have to pass when calling the script with `--rule-texts` key. Some examples of rule texts files available in [tests directory](https://github.com/danmar/cppcheck/blob/main/addons/test/misra/).
99
+ [y2038.py](https://github.com/danmar/cppcheck/blob/main/addons/y2038.py)
10-
Checks Linux system for [year 2038 problem](https://en.wikipedia.org/wiki/Year_2038_problem) safety. This required [modified environment](https://github.com/3adev/y2038). See complete description [here](https://github.com/danmar/cppcheck/blob/main/addons/doc/y2038.txt).
10+
Checks code for [year 2038 problem](https://en.wikipedia.org/wiki/Year_2038_problem) safety. See complete description [here](https://github.com/danmar/cppcheck/blob/main/addons/doc/y2038.md).
1111
+ [threadsafety.py](https://github.com/danmar/cppcheck/blob/main/addons/threadsafety.py)
1212
Analyse Cppcheck dump files to locate threadsafety issues like static local objects used by multiple threads.
1313
+ [naming.py](https://github.com/danmar/cppcheck/blob/main/addons/naming.py)
@@ -50,6 +50,11 @@ Addons are scripts that analyses Cppcheck dump files to check compatibility with
5050
cppcheck --addon=misc src/test.c
5151
```
5252

53+
For project-wide analysis with compile_commands.json:
54+
```bash
55+
cppcheck --project=build/compile_commands.json --addon=y2038
56+
```
57+
5358
It is also possible to call scripts as follows:
5459
```bash
5560
cppcheck --dump --quiet src/test.c

addons/doc/y2038.md

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
# README of the Y2038 cppcheck addon
2+
3+
## Contents
4+
5+
- [README of the Y2038 cppcheck addon](#readme-of-the-y2038-cppcheck-addon)
6+
- [Contents](#contents)
7+
- [What is Y2038?](#what-is-y2038)
8+
- [What is the Y2038 cppcheck addon?](#what-is-the-y2038-cppcheck-addon)
9+
- [How does the Y2038 cppcheck addon work?](#how-does-the-y2038-cppcheck-addon-work)
10+
- [Primary Usage: Cppcheck Addon Integration (`y2038.py`)](#primary-usage-cppcheck-addon-integration-y2038py)
11+
- [Implementation Details](#implementation-details)
12+
- [Requirements](#requirements)
13+
- [How to use the Y2038 cppcheck addon](#how-to-use-the-y2038-cppcheck-addon)
14+
- [**Auditing Your Project for Y2038 Compliance**](#auditing-your-project-for-y2038-compliance)
15+
- [**CI/CD Integration**](#cicd-integration)
16+
- [Testing](#testing)
17+
- [Running Y2038 Addon Tests](#running-y2038-addon-tests)
18+
- [Test Coverage](#test-coverage)
19+
- [Test Structure](#test-structure)
20+
21+
---
22+
23+
## What is Y2038?
24+
25+
In a few words:
26+
27+
Most operating systems and programming environments represent the current time as the number of seconds since the Unix epoch. In C and C++ this is exposed by time() and std::time(), with the Unix epoch defined as 00:00:00 UTC on 1 January 1970.
28+
29+
Typically this representation is stored as a 64-bit signed quantity.
30+
Some systems, mainly embedded systems and older systems, still use a 32-bit signed
31+
time_t representation.
32+
33+
On January 19th, 2038 at 03:14:07 GMT, such 32-bit representations will reach
34+
their maximum positive value.
35+
36+
What happens then is unpredictable: system time might roll back to December
37+
13th, 1901 at 19:55:13, or it might keep running on until February 7th, 2106
38+
at 06:28:15 GMT, or the computer may freeze, or just about anything you can
39+
think of, plus a few ones you can't.
40+
41+
The workaround for this is to switch to a 64-bit signed representation of time
42+
as seconds from the Unix epoch. This representation will work for more than 250
43+
billion years.
44+
45+
Working around Y2038 requires fixing the Linux kernel, the C libraries, and
46+
any user code around which uses 32-bit epoch representations.
47+
48+
There is Y2038-proofing work in progress on the Linux and GNU glibc front.
49+
50+
## What is the Y2038 cppcheck addon?
51+
52+
The Y2038 cppcheck addon is a tool to help detect code which might need fixing
53+
because it is Y2038-unsafe. This may be because it uses types or functions from
54+
GNU libc or from the Linux kernel which are known not to be Y2038-proof.
55+
56+
## How does the Y2038 cppcheck addon work?
57+
58+
The Y2038 addon is a comprehensive tool designed to audit your project for Y2038 compliance. It provides a streamlined, intelligent approach to Y2038 analysis.
59+
60+
### Primary Usage: Cppcheck Integration with Project Files
61+
62+
The Y2038 addon integrates seamlessly with cppcheck's core project parsing infrastructure. For optimal analysis, use the addon with project files:
63+
64+
```bash
65+
cppcheck --project=build/compile_commands.json --addon=y2038
66+
```
67+
68+
For single files, you can also use:
69+
```bash
70+
cppcheck --addon=y2038 source_file.c
71+
```
72+
73+
#### Implementation Details
74+
75+
The addon leverages cppcheck's built-in project parsing capabilities:
76+
77+
- **Core Integration**: Y2038-related compiler flags are extracted by cppcheck core during project parsing and passed through dump file configuration
78+
- **Automatic Flag Detection**: Cppcheck automatically detects Y2038-relevant flags (`-D_TIME_BITS=64`, `-D_FILE_OFFSET_BITS=64`, `-D_USE_TIME_BITS64`) from compilation commands
79+
- **Clean Architecture**: No redundant file parsing - cppcheck handles project files once, addon focuses on analysis
80+
- **Priority Logic**: Dump file configuration (from cppcheck's project parsing) takes precedence over source code `#define` statements
81+
- **Source Fallback**: When no project configuration is available, the addon analyzes source code `#define` statements
82+
83+
This architecture ensures optimal performance and maintains clean separation of concerns between cppcheck core (project parsing) and addon (analysis logic).
84+
85+
The output is the standard Cppcheck analysis report, focused on Y2038-related issues.
86+
87+
## Requirements
88+
89+
The Y2038 addon works with any cppcheck installation and requires no additional dependencies beyond cppcheck itself.
90+
91+
For optimal Y2038 analysis, ensure your project uses a supported build system that generates `compile_commands.json`:
92+
93+
- **CMake**: Use `-DCMAKE_EXPORT_COMPILE_COMMANDS=ON`
94+
- **Bear**: For Make/Autotools projects, use `bear` to generate compile commands
95+
- **Ninja**: Use `ninja -t compdb` to generate compile commands
96+
- **Bazel**: Use `bazel aquery` with appropriate flags
97+
98+
If using `bear` for Make-based projects, install it via your package manager:
99+
100+
```bash
101+
# On Debian/Ubuntu
102+
sudo apt-get install bear
103+
104+
# On Fedora
105+
sudo dnf install bear
106+
107+
# On macOS (using Homebrew)
108+
brew install bear
109+
```
110+
111+
## How to use the Y2038 cppcheck addon
112+
113+
### **Auditing Your Project for Y2038 Compliance**
114+
115+
The Y2038 addon seamlessly integrates with your existing cppcheck workflow.
116+
117+
**For projects with compile_commands.json (recommended):**
118+
119+
```bash
120+
cppcheck --project=build/compile_commands.json --addon=y2038
121+
```
122+
123+
**For single file analysis:**
124+
125+
```bash
126+
cppcheck --addon=y2038 source_file.c
127+
```
128+
129+
**For project-wide analysis without compile_commands.json:**
130+
131+
```bash
132+
cppcheck --addon=y2038 src/
133+
```
134+
135+
The integration automatically:
136+
137+
1. **Extracts Y2038 flags** from your project's compilation commands via cppcheck's project parsing
138+
2. **Passes flag information** through dump file configuration to the addon
139+
3. **Analyzes source code** with proper Y2038 context from both build system and source directives
140+
4. **Reports Y2038 issues** using cppcheck's standard error reporting format
141+
142+
### **CI/CD Integration**
143+
144+
For CI/CD integration, use the Y2038 addon with your project's build configuration:
145+
146+
```sh
147+
# Example CI script with compile_commands.json
148+
#!/bin/bash
149+
# Generate compile_commands.json (if not already available)
150+
cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -B build
151+
# or: bear -- make
152+
153+
# Run Y2038 analysis
154+
cppcheck --project=build/compile_commands.json --addon=y2038 --error-exitcode=1
155+
156+
# The addon will return a non-zero exit code if Y2038 issues are found.
157+
# The output is the standard Cppcheck report.
158+
```
159+
160+
**For projects without compile_commands.json:**
161+
162+
```sh
163+
# Example CI script for source-only analysis
164+
#!/bin/bash
165+
cppcheck --addon=y2038 --error-exitcode=1 src/
166+
```

addons/doc/y2038.txt

Lines changed: 0 additions & 151 deletions
This file was deleted.
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/*
2+
* Shared test case for Y2038 addon compiler flag testing
3+
*
4+
* This file tests various compiler flag scenarios:
5+
* - Proper Y2038 configuration: -D_TIME_BITS=64 -D_FILE_OFFSET_BITS=64 -D_USE_TIME_BITS64
6+
* - Incorrect _TIME_BITS value: -D_TIME_BITS=32
7+
* - Incomplete configuration: -D_USE_TIME_BITS64 (without _TIME_BITS)
8+
*
9+
* The same source code is used for all scenarios - differentiation happens
10+
* through the compiler flags passed to cppcheck during dump creation.
11+
*/
12+
13+
#include <time.h>
14+
15+
int main(int argc, char **argv)
16+
{
17+
time_t current_time;
18+
struct timespec ts;
19+
20+
current_time = time(NULL);
21+
clock_gettime(CLOCK_REALTIME, &ts);
22+
23+
return 0;
24+
}
25+

0 commit comments

Comments
 (0)