Coverage Report

Created: 2025-01-24 06:31

/src/cppcheck/lib/checkexceptionsafety.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
//---------------------------------------------------------------------------
20
#ifndef checkexceptionsafetyH
21
#define checkexceptionsafetyH
22
//---------------------------------------------------------------------------
23
24
#include "check.h"
25
#include "config.h"
26
27
#include <string>
28
29
class Settings;
30
class ErrorLogger;
31
class Token;
32
class Tokenizer;
33
34
/// @addtogroup Checks
35
/// @{
36
37
38
/**
39
 * @brief %Check exception safety (exceptions shouldn't cause leaks nor corrupt data)
40
 *
41
 * The problem with these checks is that Cppcheck can't determine what the valid
42
 * values are for variables. But in some cases (dead pointers) it can be determined
43
 * that certain variable values are corrupt.
44
 */
45
46
class CPPCHECKLIB CheckExceptionSafety : public Check {
47
public:
48
    /** This constructor is used when registering the CheckClass */
49
2
    CheckExceptionSafety() : Check(myName()) {}
50
51
private:
52
    /** This constructor is used when running checks. */
53
    CheckExceptionSafety(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger)
54
763
        : Check(myName(), tokenizer, settings, errorLogger) {}
55
56
    void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override;
57
58
    /** Don't throw exceptions in destructors */
59
    void destructors();
60
61
    /** deallocating memory and then throw (dead pointer) */
62
    void deallocThrow();
63
64
    /** Don't rethrow a copy of the caught exception; use a bare throw instead */
65
    void checkRethrowCopy();
66
67
    /** @brief %Check for exceptions that are caught by value instead of by reference */
68
    void checkCatchExceptionByValue();
69
70
    /** @brief %Check for functions that throw that shouldn't */
71
    void nothrowThrows();
72
73
    /** @brief %Check for unhandled exception specification */
74
    void unhandledExceptionSpecification();
75
76
    /** @brief %Check for rethrow not from catch scope */
77
    void rethrowNoCurrentException();
78
79
    /** Don't throw exceptions in destructors */
80
    void destructorsError(const Token * tok, const std::string &className);
81
    void deallocThrowError(const Token * tok, const std::string &varname);
82
    void rethrowCopyError(const Token * tok, const std::string &varname);
83
    void catchExceptionByValueError(const Token *tok);
84
    void noexceptThrowError(const Token * tok);
85
    /** Missing exception specification */
86
    void unhandledExceptionSpecificationError(const Token * tok1, const Token * tok2, const std::string & funcname);
87
    /** Rethrow without currently handled exception */
88
    void rethrowNoCurrentExceptionError(const Token *tok);
89
90
    /** Generate all possible errors (for --errorlist) */
91
    void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override;
92
93
    /** Short description of class (for --doc) */
94
765
    static std::string myName() {
95
765
        return "Exception Safety";
96
765
    }
97
98
    /** wiki formatted description of the class (for --doc) */
99
0
    std::string classInfo() const override {
100
0
        return "Checking exception safety\n"
101
0
               "- Throwing exceptions in destructors\n"
102
0
               "- Throwing exception during invalid state\n"
103
0
               "- Throwing a copy of a caught exception instead of rethrowing the original exception\n"
104
0
               "- Exception caught by value instead of by reference\n"
105
0
               "- Throwing exception in noexcept, nothrow(), __attribute__((nothrow)) or __declspec(nothrow) function\n"
106
0
               "- Unhandled exception specification when calling function foo()\n"
107
0
               "- Rethrow without currently handled exception\n";
108
0
    }
109
};
110
/// @}
111
//---------------------------------------------------------------------------
112
#endif // checkexceptionsafetyH