parent
cc08a661e6
commit
e6f2929fac
|
@ -260,6 +260,11 @@ bool astIsContainerOwned(const Token* tok) {
|
||||||
return astIsContainer(tok) && !astIsContainerView(tok);
|
return astIsContainer(tok) && !astIsContainerView(tok);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool astIsRangeBasedForDecl(const Token* tok)
|
||||||
|
{
|
||||||
|
return Token::simpleMatch(tok->astParent(), ":") && Token::simpleMatch(tok->astParent()->astParent(), "(");
|
||||||
|
}
|
||||||
|
|
||||||
std::string astCanonicalType(const Token *expr)
|
std::string astCanonicalType(const Token *expr)
|
||||||
{
|
{
|
||||||
if (!expr)
|
if (!expr)
|
||||||
|
|
|
@ -139,6 +139,9 @@ bool astIsContainer(const Token *tok);
|
||||||
bool astIsContainerView(const Token* tok);
|
bool astIsContainerView(const Token* tok);
|
||||||
bool astIsContainerOwned(const Token* tok);
|
bool astIsContainerOwned(const Token* tok);
|
||||||
|
|
||||||
|
/** Is given token a range-declaration in a range-based for loop */
|
||||||
|
bool astIsRangeBasedForDecl(const Token* tok);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get canonical type of expression. const/static/etc are not included and neither *&.
|
* Get canonical type of expression. const/static/etc are not included and neither *&.
|
||||||
* For example:
|
* For example:
|
||||||
|
|
|
@ -1581,8 +1581,7 @@ void CheckOther::checkConstPointer()
|
||||||
const Token* const nameTok = var->nameToken();
|
const Token* const nameTok = var->nameToken();
|
||||||
// declarations of (static) pointers are (not) split up, array declarations are never split up
|
// declarations of (static) pointers are (not) split up, array declarations are never split up
|
||||||
if (tok == nameTok && (!var->isStatic() || Token::simpleMatch(nameTok->next(), "[")) &&
|
if (tok == nameTok && (!var->isStatic() || Token::simpleMatch(nameTok->next(), "[")) &&
|
||||||
// range-based for loop
|
!astIsRangeBasedForDecl(nameTok))
|
||||||
!(Token::simpleMatch(nameTok->astParent(), ":") && Token::simpleMatch(nameTok->astParent()->astParent(), "(")))
|
|
||||||
continue;
|
continue;
|
||||||
const ValueType* const vt = tok->valueType();
|
const ValueType* const vt = tok->valueType();
|
||||||
if (!vt)
|
if (!vt)
|
||||||
|
@ -1598,8 +1597,8 @@ void CheckOther::checkConstPointer()
|
||||||
deref = true;
|
deref = true;
|
||||||
else if (Token::simpleMatch(parent, "[") && parent->astOperand1() == tok && tok != nameTok)
|
else if (Token::simpleMatch(parent, "[") && parent->astOperand1() == tok && tok != nameTok)
|
||||||
deref = true;
|
deref = true;
|
||||||
else if (Token::Match(parent, "%op%") && Token::simpleMatch(parent->astParent(), "."))
|
else if (astIsRangeBasedForDecl(tok))
|
||||||
deref = true;
|
continue;
|
||||||
if (deref) {
|
if (deref) {
|
||||||
const Token* const gparent = parent->astParent();
|
const Token* const gparent = parent->astParent();
|
||||||
if (Token::Match(gparent, "%cop%") && !gparent->isUnaryOp("&") && !gparent->isUnaryOp("*"))
|
if (Token::Match(gparent, "%cop%") && !gparent->isUnaryOp("&") && !gparent->isUnaryOp("*"))
|
||||||
|
@ -1616,7 +1615,7 @@ void CheckOther::checkConstPointer()
|
||||||
} else if (Token::simpleMatch(gparent, "[") && gparent->astOperand2() == parent)
|
} else if (Token::simpleMatch(gparent, "[") && gparent->astOperand2() == parent)
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
if (Token::Match(parent, "%oror%|%comp%|&&|?|!|-"))
|
if (Token::Match(parent, "%oror%|%comp%|&&|?|!"))
|
||||||
continue;
|
continue;
|
||||||
else if (Token::simpleMatch(parent, "(") && Token::Match(parent->astOperand1(), "if|while"))
|
else if (Token::simpleMatch(parent, "(") && Token::Match(parent->astOperand1(), "if|while"))
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -6212,7 +6212,7 @@ void SymbolDatabase::setValueType(Token *tok, const ValueType &valuetype)
|
||||||
setAutoTokenProperties(autoToken);
|
setAutoTokenProperties(autoToken);
|
||||||
ValueType varvt(autovt);
|
ValueType varvt(autovt);
|
||||||
if (isconst)
|
if (isconst)
|
||||||
varvt.constness |= (1 << varvt.pointer);
|
varvt.constness |= 1;
|
||||||
setValueType(parent->previous(), varvt);
|
setValueType(parent->previous(), varvt);
|
||||||
Variable * var = const_cast<Variable *>(parent->previous()->variable());
|
Variable * var = const_cast<Variable *>(parent->previous()->variable());
|
||||||
if (var) {
|
if (var) {
|
||||||
|
|
|
@ -3124,21 +3124,36 @@ private:
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
// #10466
|
// #10466
|
||||||
|
check("typedef void* HWND;\n"
|
||||||
|
"void f(const std::vector<HWND>&v) {\n"
|
||||||
|
" for (const auto* h : v)\n"
|
||||||
|
" if (h) {}\n"
|
||||||
|
" for (const auto& h : v)\n"
|
||||||
|
" if (h) {}\n"
|
||||||
|
"}\n");
|
||||||
|
ASSERT_EQUALS("[test.cpp:5]: (style) Variable 'h' can be declared as pointer to const\n", errout.str());
|
||||||
|
|
||||||
check("void f(const std::vector<int*>& v) {\n"
|
check("void f(const std::vector<int*>& v) {\n"
|
||||||
" for (const auto& p : v)\n"
|
" for (const auto& p : v)\n"
|
||||||
" if (p == nullptr) {}\n"
|
" if (p == nullptr) {}\n"
|
||||||
" for (const auto* p : v)\n"
|
" for (const auto* p : v)\n"
|
||||||
" if (p == nullptr) {}\n"
|
" if (p == nullptr) {}\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("[test.cpp:2]: (style) Variable 'p' can be declared as pointer to const\n", errout.str());
|
||||||
|
|
||||||
check("void f(std::vector<int*>& v) {\n"
|
check("void f(std::vector<int*>& v) {\n"
|
||||||
" for (const auto& p : v)\n"
|
" for (const auto& p : v)\n"
|
||||||
" if (p == nullptr) {}\n"
|
" if (p == nullptr) {}\n"
|
||||||
" for (const auto* p : v)\n"
|
" for (const auto* p : v)\n"
|
||||||
" if (p == nullptr) {}\n"
|
" if (p == nullptr) {}\n"
|
||||||
|
" for (const int* const& p : v)\n"
|
||||||
|
" if (p == nullptr) {}\n"
|
||||||
|
" for (const int* p : v)\n"
|
||||||
|
" if (p == nullptr) {}\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS("[test.cpp:1]: (style) Parameter 'v' can be declared as reference to const\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:1]: (style) Parameter 'v' can be declared as reference to const\n"
|
||||||
|
"[test.cpp:2]: (style) Variable 'p' can be declared as pointer to const\n",
|
||||||
|
errout.str());
|
||||||
|
|
||||||
check("void f(std::vector<const int*>& v) {\n"
|
check("void f(std::vector<const int*>& v) {\n"
|
||||||
" for (const auto& p : v)\n"
|
" for (const auto& p : v)\n"
|
||||||
|
@ -3188,7 +3203,7 @@ private:
|
||||||
"[test.cpp:4]: (style) Variable 'b' can be declared as const array\n",
|
"[test.cpp:4]: (style) Variable 'b' can be declared as const array\n",
|
||||||
errout.str());
|
errout.str());
|
||||||
|
|
||||||
check("typedef void* HWND;\n"
|
check("typedef void* HWND;\n" // #11084
|
||||||
"void f(const HWND h) {\n"
|
"void f(const HWND h) {\n"
|
||||||
" if (h == nullptr) {}\n"
|
" if (h == nullptr) {}\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
|
@ -3217,6 +3232,19 @@ private:
|
||||||
" (s - 1)->v();\n"
|
" (s - 1)->v();\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
check("void f(std::vector<int*>& v) {\n" // #11085
|
||||||
|
" for (int* p : v) {\n"
|
||||||
|
" if (p) {}\n"
|
||||||
|
" }\n"
|
||||||
|
" for (auto* p : v) {\n"
|
||||||
|
" if (p) {}\n"
|
||||||
|
" }\n"
|
||||||
|
" v.clear();\n"
|
||||||
|
"}\n");
|
||||||
|
ASSERT_EQUALS("[test.cpp:2]: (style) Variable 'p' can be declared as pointer to const\n"
|
||||||
|
"[test.cpp:5]: (style) Variable 'p' can be declared as pointer to const\n",
|
||||||
|
errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void switchRedundantAssignmentTest() {
|
void switchRedundantAssignmentTest() {
|
||||||
|
|
|
@ -7741,6 +7741,7 @@ private:
|
||||||
ASSERT_EQUALS("signed short &", typeOf("short values[10]; void f() { for (auto& x : values); }", "x"));
|
ASSERT_EQUALS("signed short &", typeOf("short values[10]; void f() { for (auto& x : values); }", "x"));
|
||||||
ASSERT_EQUALS("signed int * &", typeOf("int* values[10]; void f() { for (auto& p : values); }", "p"));
|
ASSERT_EQUALS("signed int * &", typeOf("int* values[10]; void f() { for (auto& p : values); }", "p"));
|
||||||
ASSERT_EQUALS("signed int * const &", typeOf("int* values[10]; void f() { for (const auto& p : values); }", "p"));
|
ASSERT_EQUALS("signed int * const &", typeOf("int* values[10]; void f() { for (const auto& p : values); }", "p"));
|
||||||
|
ASSERT_EQUALS("const signed int *", typeOf("int* values[10]; void f() { for (const auto* p : values); }", "p"));
|
||||||
ASSERT_EQUALS("const signed int", typeOf("; const auto x = 3;", "x"));
|
ASSERT_EQUALS("const signed int", typeOf("; const auto x = 3;", "x"));
|
||||||
ASSERT_EQUALS("const signed int", typeOf("; constexpr auto x = 3;", "x"));
|
ASSERT_EQUALS("const signed int", typeOf("; constexpr auto x = 3;", "x"));
|
||||||
ASSERT_EQUALS("const signed int", typeOf("; const constexpr auto x = 3;", "x"));
|
ASSERT_EQUALS("const signed int", typeOf("; const constexpr auto x = 3;", "x"));
|
||||||
|
|
Loading…
Reference in New Issue