Coverage Report

Created: 2025-01-24 06:31

/src/cppcheck/lib/suppressions.h
Line
Count
Source (jump to first uncovered line)
1
/* -*- C++ -*-
2
 * Cppcheck - A tool for static C/C++ code analysis
3
 * Copyright (C) 2007-2024 Cppcheck team.
4
 *
5
 * This program is free software: you can redistribute it and/or modify
6
 * it under the terms of the GNU General Public License as published by
7
 * the Free Software Foundation, either version 3 of the License, or
8
 * (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
 */
18
//---------------------------------------------------------------------------
19
#ifndef suppressionsH
20
#define suppressionsH
21
//---------------------------------------------------------------------------
22
23
#include "config.h"
24
25
#include <cstddef>
26
#include <cstdint>
27
#include <istream>
28
#include <list>
29
#include <set>
30
#include <string>
31
#include <utility>
32
#include <vector>
33
34
/// @addtogroup Core
35
/// @{
36
37
class Tokenizer;
38
class ErrorMessage;
39
class ErrorLogger;
40
enum class Certainty : std::uint8_t;
41
class FileWithDetails;
42
43
/** @brief class for handling suppressions */
44
class CPPCHECKLIB SuppressionList {
45
public:
46
47
    enum class Type : std::uint8_t {
48
        unique, file, block, blockBegin, blockEnd, macro
49
    };
50
51
    struct CPPCHECKLIB ErrorMessage {
52
        std::size_t hash;
53
        std::string errorId;
54
        void setFileName(std::string s);
55
0
        const std::string &getFileName() const {
56
0
            return mFileName;
57
0
        }
58
        int lineNumber;
59
        Certainty certainty;
60
        std::string symbolNames;
61
        std::set<std::string> macroNames;
62
63
        static SuppressionList::ErrorMessage fromErrorMessage(const ::ErrorMessage &msg, const std::set<std::string> &macroNames);
64
    private:
65
        std::string mFileName;
66
    };
67
68
    struct CPPCHECKLIB Suppression {
69
0
        Suppression() = default;
70
0
        Suppression(std::string id, std::string file, int line=NO_LINE) : errorId(std::move(id)), fileName(std::move(file)), lineNumber(line) {}
71
72
0
        bool operator<(const Suppression &other) const {
73
0
            if (errorId != other.errorId)
74
0
                return errorId < other.errorId;
75
0
            if (lineNumber < other.lineNumber)
76
0
                return true;
77
0
            if (fileName != other.fileName)
78
0
                return fileName < other.fileName;
79
0
            if (symbolName != other.symbolName)
80
0
                return symbolName < other.symbolName;
81
0
            if (macroName != other.macroName)
82
0
                return macroName < other.macroName;
83
0
            if (hash != other.hash)
84
0
                return hash < other.hash;
85
0
            if (thisAndNextLine != other.thisAndNextLine)
86
0
                return thisAndNextLine;
87
0
            return false;
88
0
        }
89
90
0
        bool operator==(const Suppression &other) const {
91
0
            if (errorId != other.errorId)
92
0
                return false;
93
0
            if (lineNumber < other.lineNumber)
94
0
                return false;
95
0
            if (fileName != other.fileName)
96
0
                return false;
97
0
            if (symbolName != other.symbolName)
98
0
                return false;
99
0
            if (macroName != other.macroName)
100
0
                return false;
101
0
            if (hash != other.hash)
102
0
                return false;
103
0
            if (type != other.type)
104
0
                return false;
105
0
            if (lineBegin != other.lineBegin)
106
0
                return false;
107
0
            if (lineEnd != other.lineEnd)
108
0
                return false;
109
0
            return true;
110
0
        }
111
112
        /**
113
         * Parse inline suppression in comment
114
         * @param comment the full comment text
115
         * @param errorMessage output parameter for error message (wrong suppression attribute)
116
         * @return true if it is a inline comment.
117
         */
118
        bool parseComment(std::string comment, std::string *errorMessage);
119
120
        bool isSuppressed(const ErrorMessage &errmsg) const;
121
122
        bool isMatch(const ErrorMessage &errmsg);
123
124
        std::string getText() const;
125
126
0
        bool isLocal() const {
127
0
            return !fileName.empty() && fileName.find_first_of("?*") == std::string::npos;
128
0
        }
129
130
0
        bool isSameParameters(const Suppression &other) const {
131
0
            return errorId == other.errorId &&
132
0
                   fileName == other.fileName &&
133
0
                   lineNumber == other.lineNumber &&
134
0
                   symbolName == other.symbolName &&
135
0
                   hash == other.hash &&
136
0
                   thisAndNextLine == other.thisAndNextLine;
137
0
        }
138
139
        std::string toString() const;
140
141
        std::string errorId;
142
        std::string fileName;
143
        int lineNumber = NO_LINE;
144
        int lineBegin = NO_LINE;
145
        int lineEnd = NO_LINE;
146
        Type type = Type::unique;
147
        std::string symbolName;
148
        std::string macroName;
149
        std::size_t hash{};
150
        bool thisAndNextLine{}; // Special case for backwards compatibility: { // cppcheck-suppress something
151
        bool matched{};
152
        bool checked{}; // for inline suppressions, checked or not
153
154
        enum : std::int8_t { NO_LINE = -1 };
155
    };
156
157
    /**
158
     * @brief Don't show errors listed in the file.
159
     * @param istr Open file stream where errors can be read.
160
     * @return error message. empty upon success
161
     */
162
    std::string parseFile(std::istream &istr);
163
164
    /**
165
     * @brief Don't show errors listed in the file.
166
     * @param filename file name
167
     * @return error message. empty upon success
168
     */
169
    std::string parseXmlFile(const char *filename);
170
171
    /**
172
     * Parse multi inline suppression in comment
173
     * @param comment the full comment text
174
     * @param errorMessage output parameter for error message (wrong suppression attribute)
175
     * @return empty vector if something wrong.
176
     */
177
    static std::vector<Suppression> parseMultiSuppressComment(const std::string &comment, std::string *errorMessage);
178
179
    /**
180
     * @brief Don't show the given error.
181
     * @param line Description of error to suppress (in id:file:line format).
182
     * @return error message. empty upon success
183
     */
184
    std::string addSuppressionLine(const std::string &line);
185
186
    /**
187
     * @brief Don't show this error. File and/or line are optional. In which case
188
     * the errorId alone is used for filtering.
189
     * @param suppression suppression details
190
     * @return error message. empty upon success
191
     */
192
    std::string addSuppression(Suppression suppression);
193
194
    /**
195
     * @brief Combine list of suppressions into the current suppressions.
196
     * @param suppressions list of suppression details
197
     * @return error message. empty upon success
198
     */
199
    std::string addSuppressions(std::list<Suppression> suppressions);
200
201
    /**
202
     * @brief Updates the state of the given suppression.
203
     * @param suppression the suppression to update
204
     * @return true if suppression to update was found
205
     */
206
    bool updateSuppressionState(const SuppressionList::Suppression& suppression);
207
208
    /**
209
     * @brief Returns true if this message should not be shown to the user.
210
     * @param errmsg error message
211
     * @param global use global suppressions
212
     * @return true if this error is suppressed.
213
     */
214
    bool isSuppressed(const ErrorMessage &errmsg, bool global = true);
215
216
    /**
217
     * @brief Returns true if this message is "explicitly" suppressed. The suppression "id" must match textually exactly.
218
     * @param errmsg error message
219
     * @param global use global suppressions
220
     * @return true if this error is explicitly suppressed.
221
     */
222
    bool isSuppressedExplicitly(const ErrorMessage &errmsg, bool global = true);
223
224
    /**
225
     * @brief Returns true if this message should not be shown to the user.
226
     * @param errmsg error message
227
     * @return true if this error is suppressed.
228
     */
229
    bool isSuppressed(const ::ErrorMessage &errmsg, const std::set<std::string>& macroNames);
230
231
    /**
232
     * @brief Create an xml dump of suppressions
233
     * @param out stream to write XML to
234
     */
235
    void dump(std::ostream &out) const;
236
237
    /**
238
     * @brief Returns list of unmatched local (per-file) suppressions.
239
     * @return list of unmatched suppressions
240
     */
241
    std::list<Suppression> getUnmatchedLocalSuppressions(const FileWithDetails &file, bool unusedFunctionChecking) const;
242
243
    /**
244
     * @brief Returns list of unmatched global (glob pattern) suppressions.
245
     * @return list of unmatched suppressions
246
     */
247
    std::list<Suppression> getUnmatchedGlobalSuppressions(bool unusedFunctionChecking) const;
248
249
    /**
250
     * @brief Returns list of all suppressions.
251
     * @return list of suppressions
252
     */
253
    const std::list<Suppression> &getSuppressions() const;
254
255
    /**
256
     * @brief Marks Inline Suppressions as checked if source line is in the token stream
257
     */
258
    void markUnmatchedInlineSuppressionsAsChecked(const Tokenizer &tokenizer);
259
260
    /**
261
     * Report unmatched suppressions
262
     * @param unmatched list of unmatched suppressions (from Settings::Suppressions::getUnmatched(Local|Global)Suppressions)
263
     * @return true is returned if errors are reported
264
     */
265
    static bool reportUnmatchedSuppressions(const std::list<SuppressionList::Suppression> &unmatched, ErrorLogger &errorLogger);
266
267
private:
268
    /** @brief List of error which the user doesn't want to see. */
269
    std::list<Suppression> mSuppressions;
270
};
271
272
struct Suppressions
273
{
274
    /** @brief suppress message (--suppressions) */
275
    SuppressionList nomsg;
276
    /** @brief suppress exitcode */
277
    SuppressionList nofail;
278
};
279
280
/// @}
281
//---------------------------------------------------------------------------
282
#endif // suppressionsH