Skip to content

Commit 3f93d61

Browse files
Fix #14161 FN constVariablePointer (assignment to const pointer) (#7859)
Co-authored-by: chrchr-github <[email protected]>
1 parent c0b4c73 commit 3f93d61

File tree

6 files changed

+29
-11
lines changed

6 files changed

+29
-11
lines changed

lib/astutils.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1062,7 +1062,7 @@ bool isAliasOf(const Token *tok, nonneg int varid, bool* inconclusive)
10621062
return false;
10631063
}
10641064

1065-
bool isAliasOf(const Token* tok, const Token* expr, int* indirect)
1065+
bool isAliasOf(const Token* tok, const Token* expr, nonneg int* indirect)
10661066
{
10671067
const Token* r = nullptr;
10681068
if (indirect)
@@ -2906,7 +2906,7 @@ static bool isExpressionChangedAt(const F& getExprTok,
29062906
// TODO: Is global variable really changed by function call?
29072907
return true;
29082908
}
2909-
int i = 1;
2909+
nonneg int i = 1;
29102910
bool aliased = false;
29112911
// If we can't find the expression then assume it is an alias
29122912
auto expr = getExprTok();
@@ -2916,7 +2916,10 @@ static bool isExpressionChangedAt(const F& getExprTok,
29162916
aliased = isAliasOf(tok, expr, &i);
29172917
if (!aliased)
29182918
return false;
2919-
if (isVariableChanged(tok, indirect + i, settings, depth))
2919+
i += indirect;
2920+
if (tok->valueType() && tok->valueType()->pointer)
2921+
i = std::min(i, tok->valueType()->pointer);
2922+
if (isVariableChanged(tok, i, settings, depth))
29202923
return true;
29212924
// TODO: Try to traverse the lambda function
29222925
if (Token::Match(tok, "%var% ("))

lib/astutils.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -379,7 +379,7 @@ bool isExpressionChangedAt(const Token* expr,
379379
/// If token is an alias if another variable
380380
bool isAliasOf(const Token *tok, nonneg int varid, bool* inconclusive = nullptr);
381381

382-
bool isAliasOf(const Token* tok, const Token* expr, int* indirect = nullptr);
382+
bool isAliasOf(const Token* tok, const Token* expr, nonneg int* indirect = nullptr);
383383

384384
const Token* getArgumentStart(const Token* ftok);
385385

lib/checkother.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1916,8 +1916,13 @@ void CheckOther::checkConstPointer()
19161916
continue;
19171917
if (Token::simpleMatch(parent, "(") && Token::Match(parent->astOperand1(), "if|while"))
19181918
continue;
1919-
if (Token::simpleMatch(parent, "=") && parent->astOperand1() == tok)
1920-
continue;
1919+
if (Token::simpleMatch(parent, "=")) {
1920+
const Token* lhs = parent->astOperand1();
1921+
if (lhs == tok)
1922+
continue;
1923+
if (lhs && lhs->valueType() && lhs->valueType()->isConst(vt->pointer))
1924+
continue;
1925+
}
19211926
if (const Token* ftok = getTokenArgumentFunction(tok, argn)) {
19221927
if (ftok->function()) {
19231928
const bool isCastArg = parent->isCast() && !ftok->function()->getOverloadedFunctions().empty(); // assume that cast changes the called function

lib/symboldatabase.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2296,7 +2296,7 @@ Variable& Variable::operator=(const Variable &var) &
22962296
if (this == &var)
22972297
return *this;
22982298

2299-
ValueType* vt = nullptr;
2299+
const ValueType* vt = nullptr;
23002300
if (var.mValueType)
23012301
vt = new ValueType(*var.mValueType);
23022302

@@ -2462,7 +2462,7 @@ void Variable::setValueType(const ValueType &valueType)
24622462
if (declType && !declType->next()->valueType())
24632463
return;
24642464
}
2465-
auto* vt = new ValueType(valueType);
2465+
const auto* vt = new ValueType(valueType);
24662466
delete mValueType;
24672467
mValueType = vt;
24682468
if ((mValueType->pointer > 0) && (!isArray() || Token::Match(mNameToken->previous(), "( * %name% )")))

lib/tokenize.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1243,7 +1243,7 @@ void Tokenizer::simplifyTypedefCpp()
12431243
bool refToArray = false;
12441244
bool ptrMember = false;
12451245
bool typeOf = false;
1246-
Token *namespaceStart = nullptr;
1246+
const Token *namespaceStart = nullptr;
12471247
Token *namespaceEnd = nullptr;
12481248

12491249
// check for invalid input
@@ -3025,7 +3025,7 @@ bool Tokenizer::simplifyUsing()
30253025
ScopeInfo3 scopeInfo1;
30263026
ScopeInfo3 *currentScope1 = &scopeInfo1;
30273027
Token *startToken = list.front();
3028-
Token *endToken = nullptr;
3028+
const Token *endToken = nullptr;
30293029
bool inMemberFunc = false;
30303030
const ScopeInfo3 * memberFuncScope = nullptr;
30313031
const Token * memberFuncEnd = nullptr;
@@ -3039,7 +3039,7 @@ bool Tokenizer::simplifyUsing()
30393039
if (!currentScope1)
30403040
return substitute; // something bad happened
30413041
startToken = usingEnd->next();
3042-
endToken = const_cast<Token*>(currentScope->bodyEnd->next());
3042+
endToken = currentScope->bodyEnd->next();
30433043
if (currentScope->type == ScopeInfo3::MemberFunction) {
30443044
const ScopeInfo3 * temp = currentScope->findScope(currentScope->fullName);
30453045
if (temp) {

test/testother.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4497,6 +4497,16 @@ class TestOther : public TestFixture {
44974497
ASSERT_EQUALS("[test.cpp:2:18]: (style) Parameter 's' can be declared as pointer to const [constParameterPointer]\n"
44984498
"[test.cpp:5:18]: (style) Parameter 's' can be declared as pointer to const [constParameterPointer]\n",
44994499
errout_str());
4500+
4501+
check("struct T;\n"
4502+
"void use(const T*);\n"
4503+
"void f(T* tok0) {\n"
4504+
" T *tok1 = tok0;\n"
4505+
" const T *tok2 = tok1;\n"
4506+
" use(tok2);\n"
4507+
"}\n");
4508+
ASSERT_EQUALS("[test.cpp:4:8]: (style) Variable 'tok1' can be declared as pointer to const [constVariablePointer]\n",
4509+
errout_str());
45004510
}
45014511

45024512
void constArray() {

0 commit comments

Comments
 (0)