CI: Add selfcheck using Cppcheck Premium. Activates Misra C++ 2008 and Cert C++ 2016 checkers. (#5623)
This commit is contained in:
parent
83ac6bfa0f
commit
fc8c244675
|
@ -0,0 +1,43 @@
|
||||||
|
|
||||||
|
name: cppcheck-premium
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- 'main'
|
||||||
|
- 'releases/**'
|
||||||
|
tags:
|
||||||
|
- '2.*'
|
||||||
|
pull_request:
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-22.04 # run on the latest image only
|
||||||
|
|
||||||
|
env:
|
||||||
|
PREMIUM_VERSION: devdrop-20231105
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Download cppcheckpremium
|
||||||
|
run: |
|
||||||
|
wget https://files.cppchecksolutions.com/cppcheckpremium-${{ env.PREMIUM_VERSION }}-amd64.tar.gz
|
||||||
|
tar xzf cppcheckpremium-${{ env.PREMIUM_VERSION }}-amd64.tar.gz
|
||||||
|
|
||||||
|
- name: Generate a license file
|
||||||
|
run: |
|
||||||
|
echo cppcheck > cppcheck.lic
|
||||||
|
echo 231231 >> cppcheck.lic
|
||||||
|
echo 80000 >> cppcheck.lic
|
||||||
|
echo 57e08c39523ab54d >> cppcheck.lic
|
||||||
|
echo path:lib >> cppcheck.lic
|
||||||
|
|
||||||
|
- name: Check
|
||||||
|
run: |
|
||||||
|
cppcheckpremium-${{ env.PREMIUM_VERSION }}/premiumaddon --check-loc-license cppcheck.lic > cppcheck-premium-loc
|
||||||
|
cppcheckpremium-${{ env.PREMIUM_VERSION }}/cppcheck -j$(nproc) -D__GNUC__ -D__CPPCHECK__ --suppressions-list=cppcheckpremium-suppressions --platform=unix64 --enable=style --premium=misra-c++-2008 --premium=cert-c++-2016 --error-exitcode=1 lib
|
|
@ -0,0 +1,186 @@
|
||||||
|
|
||||||
|
# False positives
|
||||||
|
premium-misra-cpp-2008-5-17-1
|
||||||
|
premium-misra-cpp-2008-5-0-6
|
||||||
|
premium-misra-cpp-2008-7-2-1
|
||||||
|
premium-misra-cpp-2008-3-3-2
|
||||||
|
|
||||||
|
# open source warnings are handled by the selfcheck.yml
|
||||||
|
noExplicitConstructor
|
||||||
|
postfixOperator
|
||||||
|
shadowFunction
|
||||||
|
useStlAlgorithm
|
||||||
|
|
||||||
|
# we need to declare reserved identifier _CRTDBG_MAP_ALLOC
|
||||||
|
premium-cert-dcl51-cpp
|
||||||
|
|
||||||
|
# TODO: Is there unsafe allocations, in case of exceptions) in cppcheck
|
||||||
|
premium-cert-err58-cpp
|
||||||
|
|
||||||
|
# we have global objects
|
||||||
|
premium-cert-err58-cpp
|
||||||
|
|
||||||
|
# TODO: Exception objects must be nothrow copy constructible.
|
||||||
|
premium-cert-err60-cpp
|
||||||
|
|
||||||
|
# TODO should we throw Token?
|
||||||
|
premium-cert-err61-cpp
|
||||||
|
|
||||||
|
# TODO: Detect errors when converting a string to a number. The library function 'atoi()' shall not be used.
|
||||||
|
premium-cert-err62-cpp
|
||||||
|
|
||||||
|
# TODO: Can we reduce some const_cast?
|
||||||
|
premium-cert-exp55-cpp
|
||||||
|
|
||||||
|
# sometimes a void function does not have side effects
|
||||||
|
premium-misra-cpp-2008-0-1-8
|
||||||
|
|
||||||
|
# unused arguments, misra rules are too strict
|
||||||
|
premium-misra-cpp-2008-0-1-11
|
||||||
|
premium-misra-cpp-2008-0-1-12
|
||||||
|
|
||||||
|
# we sometimes don't care about return value from functions
|
||||||
|
premium-misra-cpp-2008-0-1-7
|
||||||
|
|
||||||
|
# TODO: can we prevent commented out code?
|
||||||
|
premium-misra-cpp-2008-2-7-2
|
||||||
|
premium-misra-cpp-2008-2-7-3
|
||||||
|
|
||||||
|
# NA
|
||||||
|
premium-misra-cpp-2008-2-10-1
|
||||||
|
|
||||||
|
# objects of a class often has the lowercase name of the class.
|
||||||
|
premium-misra-cpp-2008-2-10-4
|
||||||
|
|
||||||
|
# flag |= ..
|
||||||
|
premium-misra-cpp-2008-4-5-1
|
||||||
|
|
||||||
|
# Token/Variable flags are enum constants and we use those in bitwise operations by intention.
|
||||||
|
premium-misra-cpp-2008-4-5-2
|
||||||
|
|
||||||
|
# intentional addition of char to string: const std::string end(':' + cfg + ':' + Path::simplifyPath(sourcefile));
|
||||||
|
premium-misra-cpp-2008-4-5-3
|
||||||
|
|
||||||
|
# too strict operator precedence warnings
|
||||||
|
premium-misra-cpp-2008-5-0-2
|
||||||
|
|
||||||
|
# we are less strict about signedness. what bug is there here: unsigned int col = 0
|
||||||
|
premium-misra-cpp-2008-5-0-4
|
||||||
|
|
||||||
|
# intentional integral-to-float conversion
|
||||||
|
premium-misra-cpp-2008-5-0-5
|
||||||
|
|
||||||
|
# intentional addition of char literal: c = 'a' + (temp - 10);
|
||||||
|
premium-misra-cpp-2008-5-0-11
|
||||||
|
|
||||||
|
# conversion of char-to-int is intentional sometimes
|
||||||
|
premium-misra-cpp-2008-5-0-12
|
||||||
|
|
||||||
|
# pointer-to-bool conversion is common
|
||||||
|
premium-misra-cpp-2008-5-0-14
|
||||||
|
|
||||||
|
# pointer arithmetic is not uncommon in cppcheck code
|
||||||
|
premium-misra-cpp-2008-5-0-15
|
||||||
|
|
||||||
|
# it's only a problem if signed expression is negative
|
||||||
|
premium-misra-cpp-2008-5-0-21
|
||||||
|
|
||||||
|
# Intentional safe operands of &&: return !stdValue.empty() && str == getCPP();
|
||||||
|
premium-misra-cpp-2008-5-2-1
|
||||||
|
|
||||||
|
# const_cast performs intentional const casting
|
||||||
|
premium-misra-cpp-2008-5-2-5
|
||||||
|
|
||||||
|
# safe code: const char *next = static_cast<const char*>(std::memchr(pattern, ' ', pattern_len));
|
||||||
|
premium-misra-cpp-2008-5-2-8
|
||||||
|
|
||||||
|
# we intentionally cast pointer to integer when creating id for dumpfile
|
||||||
|
premium-misra-cpp-2008-5-2-9
|
||||||
|
|
||||||
|
# we intentionally mix increment with other operators in expressions
|
||||||
|
premium-misra-cpp-2008-5-2-10
|
||||||
|
|
||||||
|
# intentional array-to-pointer decay
|
||||||
|
premium-misra-cpp-2008-5-2-12
|
||||||
|
|
||||||
|
# we write !pointer by intention
|
||||||
|
premium-misra-cpp-2008-5-3-1
|
||||||
|
|
||||||
|
# for (;;)
|
||||||
|
premium-misra-cpp-2008-6-2-3
|
||||||
|
|
||||||
|
# it's not a bug to not put default at the end of a switch body
|
||||||
|
premium-misra-cpp-2008-6-4-6
|
||||||
|
|
||||||
|
# looping linked list => not well formed for loop
|
||||||
|
premium-misra-cpp-2008-6-5-1
|
||||||
|
premium-misra-cpp-2008-6-5-2
|
||||||
|
premium-misra-cpp-2008-6-5-3
|
||||||
|
premium-misra-cpp-2008-6-5-4
|
||||||
|
premium-misra-cpp-2008-6-5-5
|
||||||
|
premium-misra-cpp-2008-6-5-6
|
||||||
|
|
||||||
|
# we like early returns
|
||||||
|
premium-misra-cpp-2008-6-6-3
|
||||||
|
premium-misra-cpp-2008-6-6-4
|
||||||
|
premium-misra-cpp-2008-6-6-5
|
||||||
|
|
||||||
|
# we have local functions by intention
|
||||||
|
premium-misra-cpp-2008-7-3-1
|
||||||
|
|
||||||
|
# intentional: return reference from method to non-const reference parameter
|
||||||
|
premium-misra-cpp-2008-7-5-3
|
||||||
|
|
||||||
|
# intentional declaration of multiple variables
|
||||||
|
premium-misra-cpp-2008-8-0-1
|
||||||
|
|
||||||
|
# we intentionally don't use & before function names
|
||||||
|
premium-misra-cpp-2008-8-4-4
|
||||||
|
|
||||||
|
# cppcheck does not care about this enumerator rule
|
||||||
|
premium-misra-cpp-2008-8-5-3
|
||||||
|
|
||||||
|
# TODO Fix these
|
||||||
|
premium-misra-cpp-2008-9-3-1
|
||||||
|
|
||||||
|
# we use unions by intention sometimes
|
||||||
|
premium-misra-cpp-2008-9-5-1
|
||||||
|
|
||||||
|
# overridden methods is safe
|
||||||
|
premium-misra-cpp-2008-10-3-1
|
||||||
|
|
||||||
|
# some classes have public members by intention
|
||||||
|
premium-misra-cpp-2008-11-0-1
|
||||||
|
|
||||||
|
# rule should not apply to deleted copy assignment operator
|
||||||
|
premium-misra-cpp-2008-12-8-2
|
||||||
|
|
||||||
|
# TODO: this can be fixed by refactoring the code.
|
||||||
|
premium-misra-cpp-2008-14-6-2
|
||||||
|
|
||||||
|
# function specializations: TODO check if we should refactor
|
||||||
|
premium-misra-cpp-2008-14-8-2
|
||||||
|
|
||||||
|
# we use preprocessor when it makes sense
|
||||||
|
premium-misra-cpp-2008-16-0-1
|
||||||
|
premium-misra-cpp-2008-16-2-1
|
||||||
|
premium-misra-cpp-2008-16-2-2
|
||||||
|
premium-misra-cpp-2008-16-3-2
|
||||||
|
|
||||||
|
# TODO do we need to catch string conversion errors (using atoi)?
|
||||||
|
premium-misra-cpp-2008-18-0-2
|
||||||
|
|
||||||
|
# what standard alternative is there for std::getenv
|
||||||
|
premium-misra-cpp-2008-18-0-3
|
||||||
|
|
||||||
|
# <ctime> is used by intention
|
||||||
|
premium-misra-cpp-2008-18-0-4
|
||||||
|
|
||||||
|
# code is safe. we use std::strcmp by intention
|
||||||
|
premium-misra-cpp-2008-18-0-5
|
||||||
|
|
||||||
|
# we do avoid using new/delete
|
||||||
|
premium-misra-cpp-2008-18-4-1
|
||||||
|
|
||||||
|
# <cstdio> is used by intention
|
||||||
|
premium-misra-cpp-2008-27-0-1
|
|
@ -33,6 +33,8 @@ struct Analyzer {
|
||||||
struct Action {
|
struct Action {
|
||||||
|
|
||||||
Action() = default;
|
Action() = default;
|
||||||
|
Action(const Action&) = default;
|
||||||
|
Action& operator=(const Action& rhs) = default;
|
||||||
|
|
||||||
template<class T,
|
template<class T,
|
||||||
REQUIRES("T must be convertible to unsigned int", std::is_convertible<T, unsigned int> ),
|
REQUIRES("T must be convertible to unsigned int", std::is_convertible<T, unsigned int> ),
|
||||||
|
|
|
@ -2241,7 +2241,7 @@ bool isScopeBracket(const Token* tok)
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T, REQUIRES("T must be a Token class", std::is_convertible<T*, const Token*> )>
|
template<class T, REQUIRES("T must be a Token class", std::is_convertible<T*, const Token*> )>
|
||||||
T* getTokenArgumentFunctionImpl(T* tok, int& argn)
|
static T* getTokenArgumentFunctionImpl(T* tok, int& argn)
|
||||||
{
|
{
|
||||||
argn = -1;
|
argn = -1;
|
||||||
{
|
{
|
||||||
|
@ -2892,7 +2892,7 @@ const Token* findThisChanged(const Token* start, const Token* end, int indirect,
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Find>
|
template<class Find>
|
||||||
const Token* findExpressionChangedImpl(const Token* expr,
|
static const Token* findExpressionChangedImpl(const Token* expr,
|
||||||
const Token* start,
|
const Token* start,
|
||||||
const Token* end,
|
const Token* end,
|
||||||
const Settings* settings,
|
const Settings* settings,
|
||||||
|
@ -3095,7 +3095,7 @@ const Token *findLambdaStartToken(const Token *last)
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
T* findLambdaEndTokenGeneric(T* first)
|
static T* findLambdaEndTokenGeneric(T* first)
|
||||||
{
|
{
|
||||||
auto maybeLambda = [](T* tok) -> bool {
|
auto maybeLambda = [](T* tok) -> bool {
|
||||||
while (Token::Match(tok, "*|%name%|::|>")) {
|
while (Token::Match(tok, "*|%name%|::|>")) {
|
||||||
|
|
|
@ -995,7 +995,7 @@ static bool checkFloatRelation(const std::string &op, const double value1, const
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
T getvalue3(const T value1, const T value2)
|
static T getvalue3(const T value1, const T value2)
|
||||||
{
|
{
|
||||||
const T min = std::min(value1, value2);
|
const T min = std::min(value1, value2);
|
||||||
if (min== std::numeric_limits<T>::max())
|
if (min== std::numeric_limits<T>::max())
|
||||||
|
|
|
@ -16,7 +16,8 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#ifndef checkersH
|
||||||
|
#define checkersH
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@ -44,4 +45,4 @@ namespace checkers {
|
||||||
extern CPPCHECKLIB const std::map<std::string, std::string> misraRuleSeverity;
|
extern CPPCHECKLIB const std::map<std::string, std::string> misraRuleSeverity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -16,7 +16,8 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#ifndef checkersReportH
|
||||||
|
#define checkersReportH
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
|
@ -44,4 +45,4 @@ private:
|
||||||
int mAllCheckersCount = 0;
|
int mAllCheckersCount = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -2178,6 +2178,10 @@ Variable& Variable::operator=(const Variable &var)
|
||||||
if (this == &var)
|
if (this == &var)
|
||||||
return *this;
|
return *this;
|
||||||
|
|
||||||
|
ValueType* vt = nullptr;
|
||||||
|
if (var.mValueType)
|
||||||
|
vt = new ValueType(*var.mValueType);
|
||||||
|
|
||||||
mNameToken = var.mNameToken;
|
mNameToken = var.mNameToken;
|
||||||
mTypeStartToken = var.mTypeStartToken;
|
mTypeStartToken = var.mTypeStartToken;
|
||||||
mTypeEndToken = var.mTypeEndToken;
|
mTypeEndToken = var.mTypeEndToken;
|
||||||
|
@ -2188,9 +2192,7 @@ Variable& Variable::operator=(const Variable &var)
|
||||||
mScope = var.mScope;
|
mScope = var.mScope;
|
||||||
mDimensions = var.mDimensions;
|
mDimensions = var.mDimensions;
|
||||||
delete mValueType;
|
delete mValueType;
|
||||||
mValueType = nullptr;
|
mValueType = vt;
|
||||||
if (var.mValueType)
|
|
||||||
mValueType = new ValueType(*var.mValueType);
|
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@ -2344,9 +2346,9 @@ void Variable::setValueType(const ValueType &valueType)
|
||||||
if (declType && !declType->next()->valueType())
|
if (declType && !declType->next()->valueType())
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
ValueType* vt = new ValueType(valueType);
|
||||||
delete mValueType;
|
delete mValueType;
|
||||||
mValueType = nullptr;
|
mValueType = vt;
|
||||||
mValueType = new ValueType(valueType);
|
|
||||||
if ((mValueType->pointer > 0) && (!isArray() || Token::Match(mNameToken->previous(), "( * %name% )")))
|
if ((mValueType->pointer > 0) && (!isArray() || Token::Match(mNameToken->previous(), "( * %name% )")))
|
||||||
setFlag(fIsPointer, true);
|
setFlag(fIsPointer, true);
|
||||||
setFlag(fIsConst, mValueType->constness & (1U << mValueType->pointer));
|
setFlag(fIsConst, mValueType->constness & (1U << mValueType->pointer));
|
||||||
|
@ -6359,7 +6361,7 @@ static void setAutoTokenProperties(Token * const autoTok)
|
||||||
autoTok->isStandardType(true);
|
autoTok->isStandardType(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isContainerYieldElement(Library::Container::Yield yield)
|
static bool isContainerYieldElement(Library::Container::Yield yield)
|
||||||
{
|
{
|
||||||
return yield == Library::Container::Yield::ITEM || yield == Library::Container::Yield::AT_INDEX ||
|
return yield == Library::Container::Yield::ITEM || yield == Library::Container::Yield::AT_INDEX ||
|
||||||
yield == Library::Container::Yield::BUFFER || yield == Library::Container::Yield::BUFFER_NT;
|
yield == Library::Container::Yield::BUFFER || yield == Library::Container::Yield::BUFFER_NT;
|
||||||
|
|
|
@ -618,7 +618,6 @@ namespace {
|
||||||
std::pair<Token*, Token*> mRangeType;
|
std::pair<Token*, Token*> mRangeType;
|
||||||
std::pair<Token*, Token*> mRangeTypeQualifiers;
|
std::pair<Token*, Token*> mRangeTypeQualifiers;
|
||||||
std::pair<Token*, Token*> mRangeAfterVar;
|
std::pair<Token*, Token*> mRangeAfterVar;
|
||||||
std::string mTypedefName; // Name of typedef type
|
|
||||||
Token* mNameToken{nullptr};
|
Token* mNameToken{nullptr};
|
||||||
bool mFail = false;
|
bool mFail = false;
|
||||||
bool mReplaceFailed = false;
|
bool mReplaceFailed = false;
|
||||||
|
@ -643,7 +642,6 @@ namespace {
|
||||||
if (Token::Match(nameToken, "%name% ;")) {
|
if (Token::Match(nameToken, "%name% ;")) {
|
||||||
mRangeType = rangeBefore;
|
mRangeType = rangeBefore;
|
||||||
mRangeTypeQualifiers = rangeQualifiers;
|
mRangeTypeQualifiers = rangeQualifiers;
|
||||||
mTypedefName = nameToken->str();
|
|
||||||
Token* typeName = rangeBefore.second->previous();
|
Token* typeName = rangeBefore.second->previous();
|
||||||
if (typeName->isKeyword()) {
|
if (typeName->isKeyword()) {
|
||||||
(void)num;
|
(void)num;
|
||||||
|
|
|
@ -2237,7 +2237,7 @@ struct SingleRange {
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
SingleRange<T> MakeSingleRange(T& x)
|
static SingleRange<T> MakeSingleRange(T& x)
|
||||||
{
|
{
|
||||||
return {&x};
|
return {&x};
|
||||||
}
|
}
|
||||||
|
@ -6804,7 +6804,7 @@ ValuePtr<InferModel> ValueFlow::makeIntegralInferModel() {
|
||||||
return IntegralInferModel{};
|
return IntegralInferModel{};
|
||||||
}
|
}
|
||||||
|
|
||||||
ValueFlow::Value inferCondition(const std::string& op, const Token* varTok, MathLib::bigint val)
|
static ValueFlow::Value inferCondition(const std::string& op, const Token* varTok, MathLib::bigint val)
|
||||||
{
|
{
|
||||||
if (!varTok)
|
if (!varTok)
|
||||||
return ValueFlow::Value{};
|
return ValueFlow::Value{};
|
||||||
|
@ -7374,7 +7374,7 @@ struct MultiValueFlowAnalyzer : ValueFlowAnalyzer {
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class Key, class F>
|
template<class Key, class F>
|
||||||
bool productParams(const Settings* settings, const std::unordered_map<Key, std::list<ValueFlow::Value>>& vars, F f)
|
static bool productParams(const Settings* settings, const std::unordered_map<Key, std::list<ValueFlow::Value>>& vars, F f)
|
||||||
{
|
{
|
||||||
using Args = std::vector<std::unordered_map<Key, ValueFlow::Value>>;
|
using Args = std::vector<std::unordered_map<Key, ValueFlow::Value>>;
|
||||||
Args args(1);
|
Args args(1);
|
||||||
|
@ -7607,7 +7607,7 @@ struct IteratorRange
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class Iterator>
|
template<class Iterator>
|
||||||
IteratorRange<Iterator> MakeIteratorRange(Iterator start, Iterator last)
|
static IteratorRange<Iterator> MakeIteratorRange(Iterator start, Iterator last)
|
||||||
{
|
{
|
||||||
return {start, last};
|
return {start, last};
|
||||||
}
|
}
|
||||||
|
@ -8260,7 +8260,7 @@ static const Token* solveExprValue(const Token* expr, ValueFlow::Value& value)
|
||||||
value);
|
value);
|
||||||
}
|
}
|
||||||
|
|
||||||
ValuePtr<Analyzer> makeAnalyzer(const Token* exprTok, ValueFlow::Value value, const TokenList& tokenlist, const Settings* settings)
|
static ValuePtr<Analyzer> makeAnalyzer(const Token* exprTok, ValueFlow::Value value, const TokenList& tokenlist, const Settings* settings)
|
||||||
{
|
{
|
||||||
if (value.isContainerSizeValue())
|
if (value.isContainerSizeValue())
|
||||||
return ContainerExpressionAnalyzer(exprTok, std::move(value), tokenlist, settings);
|
return ContainerExpressionAnalyzer(exprTok, std::move(value), tokenlist, settings);
|
||||||
|
@ -8268,7 +8268,7 @@ ValuePtr<Analyzer> makeAnalyzer(const Token* exprTok, ValueFlow::Value value, co
|
||||||
return ExpressionAnalyzer(expr, std::move(value), tokenlist, settings);
|
return ExpressionAnalyzer(expr, std::move(value), tokenlist, settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
ValuePtr<Analyzer> makeReverseAnalyzer(const Token* exprTok, ValueFlow::Value value, const TokenList& tokenlist, const Settings* settings)
|
static ValuePtr<Analyzer> makeReverseAnalyzer(const Token* exprTok, ValueFlow::Value value, const TokenList& tokenlist, const Settings* settings)
|
||||||
{
|
{
|
||||||
if (value.isContainerSizeValue())
|
if (value.isContainerSizeValue())
|
||||||
return ContainerExpressionAnalyzer(exprTok, std::move(value), tokenlist, settings);
|
return ContainerExpressionAnalyzer(exprTok, std::move(value), tokenlist, settings);
|
||||||
|
@ -9380,7 +9380,7 @@ struct ValueFlowPassAdaptor : ValueFlowPass {
|
||||||
const char* mName = nullptr;
|
const char* mName = nullptr;
|
||||||
bool mCPP = false;
|
bool mCPP = false;
|
||||||
F mRun;
|
F mRun;
|
||||||
ValueFlowPassAdaptor(const char* pname, bool pcpp, F prun) : mName(pname), mCPP(pcpp), mRun(prun) {}
|
ValueFlowPassAdaptor(const char* pname, bool pcpp, F prun) : ValueFlowPass(), mName(pname), mCPP(pcpp), mRun(prun) {}
|
||||||
const char* name() const override {
|
const char* name() const override {
|
||||||
return mName;
|
return mName;
|
||||||
}
|
}
|
||||||
|
@ -9394,7 +9394,7 @@ struct ValueFlowPassAdaptor : ValueFlowPass {
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class F>
|
template<class F>
|
||||||
ValueFlowPassAdaptor<F> makeValueFlowPassAdaptor(const char* name, bool cpp, F run)
|
static ValueFlowPassAdaptor<F> makeValueFlowPassAdaptor(const char* name, bool cpp, F run)
|
||||||
{
|
{
|
||||||
return {name, cpp, run};
|
return {name, cpp, run};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
// For a release version x.y.z the MAJOR should be x and both MINOR and DEVMINOR should be y.
|
// For a release version x.y.z the MAJOR should be x and both MINOR and DEVMINOR should be y.
|
||||||
// After a release the DEVMINOR is incremented. MAJOR=x MINOR=y, DEVMINOR=y+1
|
// After a release the DEVMINOR is incremented. MAJOR=x MINOR=y, DEVMINOR=y+1
|
||||||
|
|
||||||
|
#ifndef versionH
|
||||||
|
#define versionH
|
||||||
|
|
||||||
#define CPPCHECK_MAJOR_VERSION 2
|
#define CPPCHECK_MAJOR_VERSION 2
|
||||||
#define CPPCHECK_MINOR_VERSION 12
|
#define CPPCHECK_MINOR_VERSION 12
|
||||||
#define CPPCHECK_DEVMINOR_VERSION 13
|
#define CPPCHECK_DEVMINOR_VERSION 13
|
||||||
|
@ -16,3 +19,5 @@
|
||||||
#define CPPCHECK_VERSION CPPCHECK_MAJOR_VERSION,CPPCHECK_MINOR_VERSION,99,0
|
#define CPPCHECK_VERSION CPPCHECK_MAJOR_VERSION,CPPCHECK_MINOR_VERSION,99,0
|
||||||
#endif
|
#endif
|
||||||
#define LEGALCOPYRIGHT L"Copyright (C) 2007-2023 Cppcheck team."
|
#define LEGALCOPYRIGHT L"Copyright (C) 2007-2023 Cppcheck team."
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue