Skip to content

Commit ab24e3a

Browse files
Fix remaining example from #11599, FN #11646, fix crash (#4929)
* Fix remainig example from #11599 * Fix FP, new warnings * More warnings * Use getTokenArgumentFunction() * Fix crash * Fix #11646 constParameter not reported with "const * const" parameter * Fix test * Fix new warnings * Add suppression * Add const, fix suppression
1 parent 8043930 commit ab24e3a

7 files changed

Lines changed: 59 additions & 34 deletions

File tree

lib/astutils.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2409,9 +2409,6 @@ bool isVariableChangedByFunctionCall(const Token *tok, int indirect, const Setti
24092409
if (indirect > 0) {
24102410
if (arg->isPointer() && !(arg->valueType() && arg->valueType()->isConst(indirect)))
24112411
return true;
2412-
// If const is applied to the pointer, then the value can still be modified
2413-
if (Token::simpleMatch(arg->typeEndToken(), "* const"))
2414-
return true;
24152412
if (arg->isArray() || (!arg->isPointer() && (!arg->valueType() || arg->valueType()->type == ValueType::UNKNOWN_TYPE)))
24162413
return true;
24172414
}

lib/checkother.cpp

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1391,14 +1391,6 @@ static bool isVariableMutableInInitializer(const Token* start, const Token * end
13911391
return false;
13921392
}
13931393

1394-
static const Token* isFuncArg(const Token* tok) {
1395-
while (Token::simpleMatch(tok, ","))
1396-
tok = tok->astParent();
1397-
if (Token::simpleMatch(tok, "(") && Token::Match(tok->astOperand1(), "%name% ("))
1398-
return tok->astOperand1();
1399-
return nullptr;
1400-
}
1401-
14021394
void CheckOther::checkConstVariable()
14031395
{
14041396
if (!mSettings->severity.isEnabled(Severity::style) || mTokenizer->isC())
@@ -1481,7 +1473,8 @@ void CheckOther::checkConstVariable()
14811473
}
14821474
if (tok->isUnaryOp("&") && Token::Match(tok, "& %varid%", var->declarationId())) {
14831475
const Token* opTok = tok->astParent();
1484-
if (opTok->isComparisonOp() || opTok->isAssignmentOp() || opTok->isCalculation()) {
1476+
int argn = -1;
1477+
if (opTok && (opTok->isComparisonOp() || opTok->isAssignmentOp() || opTok->isCalculation())) {
14851478
if (opTok->isComparisonOp() || opTok->isCalculation()) {
14861479
if (opTok->astOperand1() != tok)
14871480
opTok = opTok->astOperand1();
@@ -1490,7 +1483,7 @@ void CheckOther::checkConstVariable()
14901483
}
14911484
if (opTok->valueType() && var->valueType() && opTok->valueType()->isConst(var->valueType()->pointer))
14921485
continue;
1493-
} else if (const Token* ftok = isFuncArg(opTok)) {
1486+
} else if (const Token* ftok = getTokenArgumentFunction(tok, argn)) {
14941487
bool inconclusive{};
14951488
if (var->valueType() && !isVariableChangedByFunctionCall(ftok, var->valueType()->pointer, var->declarationId(), mSettings, &inconclusive) && !inconclusive)
14961489
continue;
@@ -1572,6 +1565,7 @@ void CheckOther::checkConstPointer()
15721565
const Token* const gparent = parent->astParent();
15731566
if (Token::Match(gparent, "%cop%") && !gparent->isUnaryOp("&") && !gparent->isUnaryOp("*"))
15741567
continue;
1568+
int argn = -1;
15751569
if (Token::simpleMatch(gparent, "return")) {
15761570
const Function* function = gparent->scope()->function;
15771571
if (function && (!Function::returnsReference(function) || Function::returnsConst(function)))
@@ -1589,16 +1583,27 @@ void CheckOther::checkConstPointer()
15891583
continue;
15901584
} else if (Token::simpleMatch(gparent, "[") && gparent->astOperand2() == parent)
15911585
continue;
1592-
else if (const Token* ftok = isFuncArg(gparent)) {
1586+
else if (const Token* ftok = getTokenArgumentFunction(parent, argn)) {
15931587
bool inconclusive{};
15941588
if (!isVariableChangedByFunctionCall(ftok, vt->pointer, var->declarationId(), mSettings, &inconclusive) && !inconclusive)
15951589
continue;
15961590
}
15971591
} else {
1592+
int argn = -1;
15981593
if (Token::Match(parent, "%oror%|%comp%|&&|?|!|-"))
15991594
continue;
16001595
else if (Token::simpleMatch(parent, "(") && Token::Match(parent->astOperand1(), "if|while"))
16011596
continue;
1597+
else if (const Token* ftok = getTokenArgumentFunction(tok, argn)) {
1598+
if (ftok->function() && !parent->isCast()) {
1599+
const Variable* argVar = ftok->function()->getArgumentVar(argn);
1600+
if (argVar && argVar->valueType() && argVar->valueType()->isConst(vt->pointer)) {
1601+
bool inconclusive{};
1602+
if (!isVariableChangedByFunctionCall(ftok, vt->pointer, var->declarationId(), mSettings, &inconclusive) && !inconclusive)
1603+
continue;
1604+
}
1605+
}
1606+
}
16021607
}
16031608
nonConstPointers.emplace_back(var);
16041609
}

lib/templatesimplifier.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2409,7 +2409,7 @@ static Token *skipTernaryOp(Token *tok, const Token *backToken)
24092409
return tok;
24102410
}
24112411

2412-
void TemplateSimplifier::simplifyTemplateArgs(Token *start, Token *end)
2412+
void TemplateSimplifier::simplifyTemplateArgs(Token *start, const Token *end)
24132413
{
24142414
// start could be erased so use the token before start if available
24152415
Token * first = (start && start->previous()) ? start->previous() : mTokenList.front();
@@ -2599,7 +2599,7 @@ static bool validTokenEnd(bool bounded, const Token *tok, const Token *backToken
25992599

26002600
// TODO: This is not the correct class for simplifyCalculations(), so it
26012601
// should be moved away.
2602-
bool TemplateSimplifier::simplifyCalculations(Token* frontToken, Token *backToken, bool isTemplate)
2602+
bool TemplateSimplifier::simplifyCalculations(Token* frontToken, const Token *backToken, bool isTemplate)
26032603
{
26042604
bool ret = false;
26052605
const bool bounded = frontToken || backToken;

lib/templatesimplifier.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -327,13 +327,13 @@ class CPPCHECKLIB TemplateSimplifier {
327327
* @return true if modifications to token-list are done.
328328
* false if no modifications are done.
329329
*/
330-
bool simplifyCalculations(Token* frontToken = nullptr, Token *backToken = nullptr, bool isTemplate = true);
330+
bool simplifyCalculations(Token* frontToken = nullptr, const Token *backToken = nullptr, bool isTemplate = true);
331331

332332
/** Simplify template instantiation arguments.
333333
* @param start first token of arguments
334334
* @param end token following last argument token
335335
*/
336-
void simplifyTemplateArgs(Token *start, Token *end);
336+
void simplifyTemplateArgs(Token *start, const Token *end);
337337

338338
private:
339339
/**

lib/valueflow.cpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2028,7 +2028,7 @@ static Analyzer::Result valueFlowForward(Token* startToken,
20282028
const Token* endToken,
20292029
const Token* exprTok,
20302030
ValueFlow::Value value,
2031-
TokenList* const tokenlist,
2031+
const TokenList* const tokenlist,
20322032
const Settings* settings,
20332033
SourceLocation loc = SourceLocation::current())
20342034
{
@@ -2044,7 +2044,7 @@ static Analyzer::Result valueFlowForward(Token* startToken,
20442044
const Token* endToken,
20452045
const Token* exprTok,
20462046
std::list<ValueFlow::Value> values,
2047-
TokenList* const tokenlist,
2047+
const TokenList* const tokenlist,
20482048
const Settings* settings,
20492049
SourceLocation loc = SourceLocation::current())
20502050
{
@@ -2073,7 +2073,7 @@ static Analyzer::Result valueFlowForward(Token* startToken,
20732073
static Analyzer::Result valueFlowForwardRecursive(Token* top,
20742074
const Token* exprTok,
20752075
std::list<ValueFlow::Value> values,
2076-
TokenList* const tokenlist,
2076+
const TokenList* const tokenlist,
20772077
const Settings* settings,
20782078
SourceLocation loc = SourceLocation::current())
20792079
{
@@ -2091,7 +2091,7 @@ static void valueFlowReverse(Token* tok,
20912091
const Token* const endToken,
20922092
const Token* const varToken,
20932093
std::list<ValueFlow::Value> values,
2094-
TokenList* tokenlist,
2094+
const TokenList* tokenlist,
20952095
const Settings* settings,
20962096
SourceLocation loc = SourceLocation::current())
20972097
{
@@ -2103,7 +2103,7 @@ static void valueFlowReverse(Token* tok,
21032103
}
21042104

21052105
// Deprecated
2106-
static void valueFlowReverse(TokenList* tokenlist,
2106+
static void valueFlowReverse(const TokenList* tokenlist,
21072107
Token* tok,
21082108
const Token* const varToken,
21092109
ValueFlow::Value val,
@@ -6999,7 +6999,7 @@ static void valueFlowForLoopSimplify(Token* const bodyStart,
69996999
}
70007000
}
70017001

7002-
static void valueFlowForLoopSimplifyAfter(Token* fortok, nonneg int varid, const MathLib::bigint num, TokenList* tokenlist, const Settings* settings)
7002+
static void valueFlowForLoopSimplifyAfter(Token* fortok, nonneg int varid, const MathLib::bigint num, const TokenList* tokenlist, const Settings* settings)
70037003
{
70047004
const Token *vartok = nullptr;
70057005
for (const Token *tok = fortok; tok; tok = tok->next()) {
@@ -7316,7 +7316,7 @@ static void valueFlowInjectParameter(TokenList* tokenlist,
73167316
}
73177317
}
73187318

7319-
static void valueFlowInjectParameter(TokenList* tokenlist,
7319+
static void valueFlowInjectParameter(const TokenList* tokenlist,
73207320
const Settings* settings,
73217321
const Variable* arg,
73227322
const Scope* functionScope,
@@ -7727,7 +7727,7 @@ static void addToErrorPath(ValueFlow::Value& value, const ValueFlow::Value& from
77277727
});
77287728
}
77297729

7730-
static std::vector<Token*> findAllUsages(const Variable* var, Token* start)
7730+
static std::vector<Token*> findAllUsages(const Variable* var, Token* start) // cppcheck-suppress constParameter // FP
77317731
{
77327732
std::vector<Token*> result;
77337733
const Scope* scope = var->scope();
@@ -8713,7 +8713,7 @@ struct ContainerConditionHandler : ConditionHandler {
87138713
}
87148714
};
87158715

8716-
static void valueFlowDynamicBufferSize(TokenList* tokenlist, SymbolDatabase* symboldatabase, const Settings* settings)
8716+
static void valueFlowDynamicBufferSize(const TokenList* tokenlist, SymbolDatabase* symboldatabase, const Settings* settings)
87178717
{
87188718
auto getBufferSizeFromAllocFunc = [&](const Token* funcTok) -> MathLib::bigint {
87198719
MathLib::bigint sizeValue = -1;

test/testother.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3455,6 +3455,21 @@ class TestOther : public TestFixture {
34553455
"[test.cpp:14]: (style) Parameter 's' can be declared as pointer to const\n",
34563456
errout.str());
34573457

3458+
check("void g(int, const int*);\n"
3459+
"void h(const int*);\n"
3460+
"void f(int* p) {\n"
3461+
" g(1, p);\n"
3462+
" h(p);\n"
3463+
"}\n");
3464+
ASSERT_EQUALS("[test.cpp:3]: (style) Parameter 'p' can be declared as pointer to const\n",
3465+
errout.str());
3466+
3467+
check("void f(int, const int*);\n"
3468+
"void f(int i, int* p) {\n"
3469+
" f(i, const_cast<const int*>(p));\n"
3470+
"}\n");
3471+
ASSERT_EQUALS("", errout.str());
3472+
34583473
check("struct S { int a; };\n"
34593474
"void f(std::vector<S>& v, int b) {\n"
34603475
" size_t n = v.size();\n"
@@ -3465,6 +3480,18 @@ class TestOther : public TestFixture {
34653480
" }\n"
34663481
"}\n");
34673482
ASSERT_EQUALS("[test.cpp:5]: (style) Variable 's' can be declared as reference to const\n", errout.str()); // don't crash
3483+
3484+
check("void f(int& i) {\n"
3485+
" new (&i) int();\n"
3486+
"}\n");
3487+
ASSERT_EQUALS("", errout.str()); // don't crash
3488+
3489+
check("class C;\n" // #11646
3490+
"void g(const C* const p);\n"
3491+
"void f(C* c) {\n"
3492+
" g(c);\n"
3493+
"}\n");
3494+
ASSERT_EQUALS("[test.cpp:3]: (style) Parameter 'c' can be declared as pointer to const\n", errout.str());
34683495
}
34693496

34703497
void switchRedundantAssignmentTest() {

test/testuninitvar.cpp

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5241,8 +5241,7 @@ class TestUninitVar : public TestFixture {
52415241
" s.x = 42;\n"
52425242
" bar(&s);\n"
52435243
"}");
5244-
ASSERT_EQUALS("[test.cpp:18] -> [test.cpp:12] -> [test.cpp:8]: (warning) Uninitialized variable: s->flag\n",
5245-
errout.str());
5244+
ASSERT_EQUALS("[test.cpp:18]: (error) Uninitialized variable: &s.flag\n", errout.str());
52465245

52475246
// Ticket #2207 - False negative
52485247
valueFlowUninit("void foo() {\n"
@@ -6020,7 +6019,7 @@ class TestUninitVar : public TestFixture {
60206019
" someType_t gVar;\n"
60216020
" bar(&gVar);\n"
60226021
"}");
6023-
ASSERT_EQUALS("[test.cpp:9] -> [test.cpp:5]: (warning) Uninitialized variable: p->flags\n", errout.str());
6022+
ASSERT_EQUALS("[test.cpp:9]: (error) Uninitialized variable: &gVar\n", errout.str());
60246023

60256024
valueFlowUninit("typedef struct\n"
60266025
"{\n"
@@ -6783,10 +6782,7 @@ class TestUninitVar : public TestFixture {
67836782
" abc.a = 1;\n"
67846783
" setabc(123, &abc);\n"
67856784
"}\n");
6786-
TODO_ASSERT_EQUALS("[test.cpp:8] -> [test.cpp:3]: (error) Uninitialized variable: abc->b\n"
6787-
"[test.cpp:8] -> [test.cpp:3]: (error) Uninitialized variable: abc->c\n",
6788-
"[test.cpp:8] -> [test.cpp:3]: (warning) Uninitialized variable: abc->b\n",
6789-
errout.str());
6785+
ASSERT_EQUALS("[test.cpp:8]: (error) Uninitialized variables: &abc.b, &abc.c\n", errout.str());
67906786

67916787
valueFlowUninit("struct S { int* p; };\n" // #10463
67926788
"void f(S* in) {\n"

0 commit comments

Comments
 (0)