Fix #11084: ValueType for pointer typedef, don't warn for typedef'd pointers, improve error message (#4123)
* Fix ValueType for pointer typedef * Add test * Don't warn for typedef'd pointers, improve error message * Fix tests * Add TODO * Fix test * Set isSimplifiedTypedef() for more tokens, add test * Add test
This commit is contained in:
parent
c30333425b
commit
2ceaf308de
|
@ -1600,6 +1600,8 @@ void CheckOther::checkConstPointer()
|
||||||
const int indirect = p->isArray() ? p->dimensions().size() : 1;
|
const int indirect = p->isArray() ? p->dimensions().size() : 1;
|
||||||
if (isVariableChanged(start, p->scope()->bodyEnd, indirect, p->declarationId(), false, mSettings, mTokenizer->isCPP()))
|
if (isVariableChanged(start, p->scope()->bodyEnd, indirect, p->declarationId(), false, mSettings, mTokenizer->isCPP()))
|
||||||
continue;
|
continue;
|
||||||
|
if (p->isArgument() && p->typeStartToken() && p->typeStartToken()->isSimplifiedTypedef() && !(Token::simpleMatch(p->typeEndToken(), "*") && !p->typeEndToken()->isSimplifiedTypedef()))
|
||||||
|
continue;
|
||||||
constVariableError(p, nullptr);
|
constVariableError(p, nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1615,10 +1617,11 @@ void CheckOther::constVariableError(const Variable *var, const Function *functio
|
||||||
|
|
||||||
const std::string vartype(var->isArgument() ? "Parameter" : "Variable");
|
const std::string vartype(var->isArgument() ? "Parameter" : "Variable");
|
||||||
const std::string varname(var->name());
|
const std::string varname(var->name());
|
||||||
|
const std::string ptrRefArray = var->isArray() ? "const array" : (var->isPointer() ? "pointer to const" : "reference to const");
|
||||||
|
|
||||||
ErrorPath errorPath;
|
ErrorPath errorPath;
|
||||||
std::string id = "const" + vartype;
|
std::string id = "const" + vartype;
|
||||||
std::string message = "$symbol:" + varname + "\n" + vartype + " '$symbol' can be declared with const";
|
std::string message = "$symbol:" + varname + "\n" + vartype + " '$symbol' can be declared as " + ptrRefArray;
|
||||||
errorPath.push_back(ErrorPathItem(var ? var->nameToken() : nullptr, message));
|
errorPath.push_back(ErrorPathItem(var ? var->nameToken() : nullptr, message));
|
||||||
if (var && var->isArgument() && function && function->functionPointerUsage) {
|
if (var && var->isArgument() && function && function->functionPointerUsage) {
|
||||||
errorPath.push_front(ErrorPathItem(function->functionPointerUsage, "You might need to cast the function pointer here"));
|
errorPath.push_front(ErrorPathItem(function->functionPointerUsage, "You might need to cast the function pointer here"));
|
||||||
|
|
|
@ -602,6 +602,13 @@ public:
|
||||||
setFlag(fIncompleteVar, b);
|
setFlag(fIncompleteVar, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isSimplifiedTypedef() const {
|
||||||
|
return getFlag(fIsSimplifiedTypedef);
|
||||||
|
}
|
||||||
|
void isSimplifiedTypedef(bool b) {
|
||||||
|
setFlag(fIsSimplifiedTypedef, b);
|
||||||
|
}
|
||||||
|
|
||||||
bool isIncompleteConstant() const {
|
bool isIncompleteConstant() const {
|
||||||
return getFlag(fIsIncompleteConstant);
|
return getFlag(fIsIncompleteConstant);
|
||||||
}
|
}
|
||||||
|
@ -1285,6 +1292,7 @@ private:
|
||||||
fIsRemovedVoidParameter = (1ULL << 35), // A void function parameter has been removed
|
fIsRemovedVoidParameter = (1ULL << 35), // A void function parameter has been removed
|
||||||
fIsIncompleteConstant = (1ULL << 36),
|
fIsIncompleteConstant = (1ULL << 36),
|
||||||
fIsRestrict = (1ULL << 37), // Is this a restrict pointer type
|
fIsRestrict = (1ULL << 37), // Is this a restrict pointer type
|
||||||
|
fIsSimplifiedTypedef = (1ULL << 38),
|
||||||
};
|
};
|
||||||
|
|
||||||
Token::Type mTokType;
|
Token::Type mTokType;
|
||||||
|
|
|
@ -1378,6 +1378,9 @@ void Tokenizer::simplifyTypedef()
|
||||||
typeEnd = typeStart;
|
typeEnd = typeStart;
|
||||||
|
|
||||||
// start substituting at the typedef name by replacing it with the type
|
// start substituting at the typedef name by replacing it with the type
|
||||||
|
Token* replStart = tok2; // track first replaced token
|
||||||
|
for (Token* tok3 = typeStart; tok3->str() != ";"; tok3 = tok3->next())
|
||||||
|
tok3->isSimplifiedTypedef(true);
|
||||||
tok2->str(typeStart->str());
|
tok2->str(typeStart->str());
|
||||||
|
|
||||||
// restore qualification if it was removed
|
// restore qualification if it was removed
|
||||||
|
@ -1386,7 +1389,7 @@ void Tokenizer::simplifyTypedef()
|
||||||
tok2 = tok2->previous();
|
tok2 = tok2->previous();
|
||||||
|
|
||||||
if (globalScope) {
|
if (globalScope) {
|
||||||
tok2->insertToken("::");
|
replStart = tok2->insertToken("::");
|
||||||
tok2 = tok2->next();
|
tok2 = tok2->next();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1415,7 +1418,7 @@ void Tokenizer::simplifyTypedef()
|
||||||
startIdx = spaceIdx + 1;
|
startIdx = spaceIdx + 1;
|
||||||
}
|
}
|
||||||
tok2->previous()->insertToken(removed1.substr(startIdx));
|
tok2->previous()->insertToken(removed1.substr(startIdx));
|
||||||
tok2->previous()->insertToken("::");
|
replStart = tok2->previous()->insertToken("::");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
idx = removed1.rfind(" ::");
|
idx = removed1.rfind(" ::");
|
||||||
|
@ -1425,12 +1428,21 @@ void Tokenizer::simplifyTypedef()
|
||||||
removed1.resize(idx);
|
removed1.resize(idx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
replStart->isSimplifiedTypedef(true);
|
||||||
|
Token* constTok = Token::simpleMatch(tok2->previous(), "const") ? tok2->previous() : nullptr;
|
||||||
// add remainder of type
|
// add remainder of type
|
||||||
tok2 = TokenList::copyTokens(tok2, typeStart->next(), typeEnd);
|
tok2 = TokenList::copyTokens(tok2, typeStart->next(), typeEnd);
|
||||||
|
|
||||||
if (!pointers.empty()) {
|
if (!pointers.empty()) {
|
||||||
for (const std::string &p : pointers) {
|
for (const std::string &p : pointers) {
|
||||||
tok2->insertToken(p);
|
tok2->insertToken(p);
|
||||||
|
tok2->isSimplifiedTypedef(true);
|
||||||
|
tok2 = tok2->next();
|
||||||
|
}
|
||||||
|
if (constTok) {
|
||||||
|
constTok->deleteThis();
|
||||||
|
tok2->insertToken("const");
|
||||||
|
tok2->isSimplifiedTypedef(true);
|
||||||
tok2 = tok2->next();
|
tok2 = tok2->next();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1858,7 +1858,7 @@ private:
|
||||||
check("void f(std::string str) {\n"
|
check("void f(std::string str) {\n"
|
||||||
" std::string& s2 = str;\n"
|
" std::string& s2 = str;\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:2]: (style) Variable 's2' can be declared with const\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:2]: (style) Variable 's2' can be declared as reference to const\n", errout.str());
|
||||||
|
|
||||||
check("void f(std::string str) {\n"
|
check("void f(std::string str) {\n"
|
||||||
" const std::string& s2 = str;\n"
|
" const std::string& s2 = str;\n"
|
||||||
|
@ -2013,12 +2013,12 @@ private:
|
||||||
" int& i = x[0];\n"
|
" int& i = x[0];\n"
|
||||||
" return i;\n"
|
" return i;\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:2]: (style) Variable 'i' can be declared with const\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:2]: (style) Variable 'i' can be declared as reference to const\n", errout.str());
|
||||||
|
|
||||||
check("int f(std::vector<int>& x) {\n"
|
check("int f(std::vector<int>& x) {\n"
|
||||||
" return x[0];\n"
|
" return x[0];\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:1]: (style) Parameter 'x' can be declared with const\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:1]: (style) Parameter 'x' can be declared as reference to const\n", errout.str());
|
||||||
|
|
||||||
check("int f(std::vector<int> x) {\n"
|
check("int f(std::vector<int> x) {\n"
|
||||||
" const int& i = x[0];\n"
|
" const int& i = x[0];\n"
|
||||||
|
@ -2059,7 +2059,7 @@ private:
|
||||||
check("const int& f(std::vector<int>& x) {\n"
|
check("const int& f(std::vector<int>& x) {\n"
|
||||||
" return x[0];\n"
|
" return x[0];\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:1]: (style) Parameter 'x' can be declared with const\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:1]: (style) Parameter 'x' can be declared as reference to const\n", errout.str());
|
||||||
|
|
||||||
check("int f(std::vector<int>& x) {\n"
|
check("int f(std::vector<int>& x) {\n"
|
||||||
" x[0]++;\n"
|
" x[0]++;\n"
|
||||||
|
@ -2176,17 +2176,17 @@ private:
|
||||||
" for(auto x:v)\n"
|
" for(auto x:v)\n"
|
||||||
" x = 1;\n"
|
" x = 1;\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:1]: (style) Parameter 'v' can be declared with const\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:1]: (style) Parameter 'v' can be declared as reference to const\n", errout.str());
|
||||||
|
|
||||||
check("void f(std::vector<int>& v) {\n"
|
check("void f(std::vector<int>& v) {\n"
|
||||||
" for(auto& x:v) {}\n"
|
" for(auto& x:v) {}\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:1]: (style) Parameter 'v' can be declared with const\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:1]: (style) Parameter 'v' can be declared as reference to const\n", errout.str());
|
||||||
|
|
||||||
check("void f(std::vector<int>& v) {\n"
|
check("void f(std::vector<int>& v) {\n"
|
||||||
" for(const auto& x:v) {}\n"
|
" for(const auto& x:v) {}\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:1]: (style) Parameter 'v' can be declared with const\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:1]: (style) Parameter 'v' can be declared as reference to const\n", errout.str());
|
||||||
|
|
||||||
check("void f(int& i) {\n"
|
check("void f(int& i) {\n"
|
||||||
" int& j = i;\n"
|
" int& j = i;\n"
|
||||||
|
@ -2290,14 +2290,14 @@ private:
|
||||||
" a x;\n"
|
" a x;\n"
|
||||||
" x(i);\n"
|
" x(i);\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS("[test.cpp:4]: (style) Parameter 'i' can be declared with const\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:4]: (style) Parameter 'i' can be declared as reference to const\n", errout.str());
|
||||||
|
|
||||||
//cast or assignment to a non-const reference should prevent the warning
|
//cast or assignment to a non-const reference should prevent the warning
|
||||||
check("struct T { void dostuff() const {}};\n"
|
check("struct T { void dostuff() const {}};\n"
|
||||||
"void a(T& x) {\n"
|
"void a(T& x) {\n"
|
||||||
" x.dostuff();\n"
|
" x.dostuff();\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:2]: (style) Parameter 'x' can be declared with const\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:2]: (style) Parameter 'x' can be declared as reference to const\n", errout.str());
|
||||||
check("struct T : public U { void dostuff() const {}};\n"
|
check("struct T : public U { void dostuff() const {}};\n"
|
||||||
"void a(T& x) {\n"
|
"void a(T& x) {\n"
|
||||||
" x.dostuff();\n"
|
" x.dostuff();\n"
|
||||||
|
@ -2311,7 +2311,7 @@ private:
|
||||||
" x.dostuff();\n"
|
" x.dostuff();\n"
|
||||||
" const U& y = x\n"
|
" const U& y = x\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:2]: (style) Parameter 'x' can be declared with const\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:2]: (style) Parameter 'x' can be declared as reference to const\n", errout.str());
|
||||||
check("struct T : public U { void dostuff() const {}};\n"
|
check("struct T : public U { void dostuff() const {}};\n"
|
||||||
"void a(T& x) {\n"
|
"void a(T& x) {\n"
|
||||||
" x.dostuff();\n"
|
" x.dostuff();\n"
|
||||||
|
@ -2332,7 +2332,7 @@ private:
|
||||||
" const U& y = static_cast<const U&>(x)\n"
|
" const U& y = static_cast<const U&>(x)\n"
|
||||||
" y.mutate();\n" //to avoid warnings that y can be const
|
" y.mutate();\n" //to avoid warnings that y can be const
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:2]: (style) Parameter 'x' can be declared with const\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:2]: (style) Parameter 'x' can be declared as reference to const\n", errout.str());
|
||||||
check("struct T : public U { void dostuff() const {}};\n"
|
check("struct T : public U { void dostuff() const {}};\n"
|
||||||
"void a(T& x) {\n"
|
"void a(T& x) {\n"
|
||||||
" x.dostuff();\n"
|
" x.dostuff();\n"
|
||||||
|
@ -2345,7 +2345,7 @@ private:
|
||||||
" x.dostuff();\n"
|
" x.dostuff();\n"
|
||||||
" const U& y = dynamic_cast<const U&>(x)\n"
|
" const U& y = dynamic_cast<const U&>(x)\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:2]: (style) Parameter 'x' can be declared with const\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:2]: (style) Parameter 'x' can be declared as reference to const\n", errout.str());
|
||||||
check(
|
check(
|
||||||
"struct T : public U { void dostuff() const {}};\n"
|
"struct T : public U { void dostuff() const {}};\n"
|
||||||
"void a(T& x) {\n"
|
"void a(T& x) {\n"
|
||||||
|
@ -2353,13 +2353,13 @@ private:
|
||||||
" const U& y = dynamic_cast<U const &>(x)\n"
|
" const U& y = dynamic_cast<U const &>(x)\n"
|
||||||
"}"
|
"}"
|
||||||
);
|
);
|
||||||
ASSERT_EQUALS("[test.cpp:2]: (style) Parameter 'x' can be declared with const\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:2]: (style) Parameter 'x' can be declared as reference to const\n", errout.str());
|
||||||
check("struct T : public U { void dostuff() const {}};\n"
|
check("struct T : public U { void dostuff() const {}};\n"
|
||||||
"void a(T& x) {\n"
|
"void a(T& x) {\n"
|
||||||
" x.dostuff();\n"
|
" x.dostuff();\n"
|
||||||
" const U& y = dynamic_cast<U & const>(x)\n"
|
" const U& y = dynamic_cast<U & const>(x)\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:2]: (style) Parameter 'x' can be declared with const\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:2]: (style) Parameter 'x' can be declared as reference to const\n", errout.str());
|
||||||
check("struct T : public U { void dostuff() const {}};\n"
|
check("struct T : public U { void dostuff() const {}};\n"
|
||||||
"void a(T& x) {\n"
|
"void a(T& x) {\n"
|
||||||
" x.dostuff();\n"
|
" x.dostuff();\n"
|
||||||
|
@ -2372,7 +2372,7 @@ private:
|
||||||
" x.dostuff();\n"
|
" x.dostuff();\n"
|
||||||
" const U& y = dynamic_cast<typename const U&>(x)\n"
|
" const U& y = dynamic_cast<typename const U&>(x)\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:2]: (style) Parameter 'x' can be declared with const\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:2]: (style) Parameter 'x' can be declared as reference to const\n", errout.str());
|
||||||
check("struct T : public U { void dostuff() const {}};\n"
|
check("struct T : public U { void dostuff() const {}};\n"
|
||||||
"void a(T& x) {\n"
|
"void a(T& x) {\n"
|
||||||
" x.dostuff();\n"
|
" x.dostuff();\n"
|
||||||
|
@ -2443,7 +2443,7 @@ private:
|
||||||
" x.dostuff();\n"
|
" x.dostuff();\n"
|
||||||
" const U& y = (const U&)(x)\n"
|
" const U& y = (const U&)(x)\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:2]: (style) Parameter 'x' can be declared with const\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:2]: (style) Parameter 'x' can be declared as reference to const\n", errout.str());
|
||||||
check("struct T : public U { void dostuff() const {}};\n"
|
check("struct T : public U { void dostuff() const {}};\n"
|
||||||
"void a(T& x) {\n"
|
"void a(T& x) {\n"
|
||||||
" x.dostuff();\n"
|
" x.dostuff();\n"
|
||||||
|
@ -2456,7 +2456,7 @@ private:
|
||||||
" x.dostuff();\n"
|
" x.dostuff();\n"
|
||||||
" const U& y = (typename const U&)(x)\n"
|
" const U& y = (typename const U&)(x)\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:2]: (style) Parameter 'x' can be declared with const\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:2]: (style) Parameter 'x' can be declared as reference to const\n", errout.str());
|
||||||
check("struct T : public U { void dostuff() const {}};\n"
|
check("struct T : public U { void dostuff() const {}};\n"
|
||||||
"void a(T& x) {\n"
|
"void a(T& x) {\n"
|
||||||
" x.dostuff();\n"
|
" x.dostuff();\n"
|
||||||
|
@ -2495,7 +2495,7 @@ private:
|
||||||
"void f(int& i) {\n"
|
"void f(int& i) {\n"
|
||||||
" a()(i);\n"
|
" a()(i);\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS("[test.cpp:4]: (style) Parameter 'i' can be declared with const\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:4]: (style) Parameter 'i' can be declared as reference to const\n", errout.str());
|
||||||
|
|
||||||
// #9767
|
// #9767
|
||||||
check("void fct1(MyClass& object) {\n"
|
check("void fct1(MyClass& object) {\n"
|
||||||
|
@ -2744,7 +2744,7 @@ private:
|
||||||
" : c(i)\n"
|
" : c(i)\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
"}");
|
"}");
|
||||||
TODO_ASSERT_EQUALS("[test.cpp:16]: (style) Parameter 'i' can be declared with const\n", "", errout.str());
|
TODO_ASSERT_EQUALS("[test.cpp:16]: (style) Parameter 'i' can be declared as reference to const\n", "", errout.str());
|
||||||
|
|
||||||
check("class C\n"
|
check("class C\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
|
@ -2765,7 +2765,7 @@ private:
|
||||||
" : c(i)\n"
|
" : c(i)\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
"}");
|
"}");
|
||||||
TODO_ASSERT_EQUALS("[test.cpp:16]: (style) Parameter 'i' can be declared with const\n", "", errout.str());
|
TODO_ASSERT_EQUALS("[test.cpp:16]: (style) Parameter 'i' can be declared as reference to const\n", "", errout.str());
|
||||||
|
|
||||||
check("class C\n"
|
check("class C\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
|
@ -2786,7 +2786,7 @@ private:
|
||||||
" : c(0, i)\n"
|
" : c(0, i)\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
"}");
|
"}");
|
||||||
TODO_ASSERT_EQUALS("[test.cpp:16]: (style) Parameter 'i' can be declared with const\n", "", errout.str());
|
TODO_ASSERT_EQUALS("[test.cpp:16]: (style) Parameter 'i' can be declared as reference to const\n", "", errout.str());
|
||||||
|
|
||||||
check("void f(std::map<int, std::vector<int>> &map) {\n" // #10266
|
check("void f(std::map<int, std::vector<int>> &map) {\n" // #10266
|
||||||
" for (auto &[slave, panels] : map)\n"
|
" for (auto &[slave, panels] : map)\n"
|
||||||
|
@ -2839,7 +2839,7 @@ private:
|
||||||
void constParameterCallback() {
|
void constParameterCallback() {
|
||||||
check("int callback(std::vector<int>& x) { return x[0]; }\n"
|
check("int callback(std::vector<int>& x) { return x[0]; }\n"
|
||||||
"void f() { dostuff(callback); }");
|
"void f() { dostuff(callback); }");
|
||||||
ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:1]: (style) Parameter 'x' can be declared with const. However it seems that 'callback' is a callback function, if 'x' is declared with const you might also need to cast function pointer(s).\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:1]: (style) Parameter 'x' can be declared as reference to const. However it seems that 'callback' is a callback function, if 'x' is declared with const you might also need to cast function pointer(s).\n", errout.str());
|
||||||
|
|
||||||
// #9906
|
// #9906
|
||||||
check("class EventEngine : public IEventEngine {\n"
|
check("class EventEngine : public IEventEngine {\n"
|
||||||
|
@ -2857,51 +2857,51 @@ private:
|
||||||
"void EventEngine::signalEvent(ev::sig& signal, int revents) {\n"
|
"void EventEngine::signalEvent(ev::sig& signal, int revents) {\n"
|
||||||
" switch (signal.signum) {}\n"
|
" switch (signal.signum) {}\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:10] -> [test.cpp:13]: (style) Parameter 'signal' can be declared with const. However it seems that 'signalEvent' is a callback function, if 'signal' is declared with const you might also need to cast function pointer(s).\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:10] -> [test.cpp:13]: (style) Parameter 'signal' can be declared as reference to const. However it seems that 'signalEvent' is a callback function, if 'signal' is declared with const you might also need to cast function pointer(s).\n", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void constPointer() {
|
void constPointer() {
|
||||||
check("void foo(int *p) { return *p; }");
|
check("void foo(int *p) { return *p; }");
|
||||||
ASSERT_EQUALS("[test.cpp:1]: (style) Parameter 'p' can be declared with const\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:1]: (style) Parameter 'p' can be declared as pointer to const\n", errout.str());
|
||||||
|
|
||||||
check("void foo(int *p) { x = *p; }");
|
check("void foo(int *p) { x = *p; }");
|
||||||
ASSERT_EQUALS("[test.cpp:1]: (style) Parameter 'p' can be declared with const\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:1]: (style) Parameter 'p' can be declared as pointer to const\n", errout.str());
|
||||||
|
|
||||||
check("void foo(int *p) { int &ref = *p; ref = 12; }");
|
check("void foo(int *p) { int &ref = *p; ref = 12; }");
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
check("void foo(int *p) { x = *p + 10; }");
|
check("void foo(int *p) { x = *p + 10; }");
|
||||||
ASSERT_EQUALS("[test.cpp:1]: (style) Parameter 'p' can be declared with const\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:1]: (style) Parameter 'p' can be declared as pointer to const\n", errout.str());
|
||||||
|
|
||||||
check("void foo(int *p) { return p[10]; }");
|
check("void foo(int *p) { return p[10]; }");
|
||||||
ASSERT_EQUALS("[test.cpp:1]: (style) Parameter 'p' can be declared with const\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:1]: (style) Parameter 'p' can be declared as pointer to const\n", errout.str());
|
||||||
|
|
||||||
check("void foo(int *p) { int &ref = p[0]; ref = 12; }");
|
check("void foo(int *p) { int &ref = p[0]; ref = 12; }");
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
check("void foo(int *p) { x[*p] = 12; }");
|
check("void foo(int *p) { x[*p] = 12; }");
|
||||||
ASSERT_EQUALS("[test.cpp:1]: (style) Parameter 'p' can be declared with const\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:1]: (style) Parameter 'p' can be declared as pointer to const\n", errout.str());
|
||||||
|
|
||||||
check("void foo(int *p) { if (p) {} }");
|
check("void foo(int *p) { if (p) {} }");
|
||||||
ASSERT_EQUALS("[test.cpp:1]: (style) Parameter 'p' can be declared with const\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:1]: (style) Parameter 'p' can be declared as pointer to const\n", errout.str());
|
||||||
|
|
||||||
check("void foo(int *p) { if (p || x) {} }");
|
check("void foo(int *p) { if (p || x) {} }");
|
||||||
ASSERT_EQUALS("[test.cpp:1]: (style) Parameter 'p' can be declared with const\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:1]: (style) Parameter 'p' can be declared as pointer to const\n", errout.str());
|
||||||
|
|
||||||
check("void foo(int *p) { if (p == 0) {} }");
|
check("void foo(int *p) { if (p == 0) {} }");
|
||||||
ASSERT_EQUALS("[test.cpp:1]: (style) Parameter 'p' can be declared with const\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:1]: (style) Parameter 'p' can be declared as pointer to const\n", errout.str());
|
||||||
|
|
||||||
check("void foo(int *p) { if (!p) {} }");
|
check("void foo(int *p) { if (!p) {} }");
|
||||||
ASSERT_EQUALS("[test.cpp:1]: (style) Parameter 'p' can be declared with const\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:1]: (style) Parameter 'p' can be declared as pointer to const\n", errout.str());
|
||||||
|
|
||||||
check("void foo(int *p) { if (*p > 123) {} }");
|
check("void foo(int *p) { if (*p > 123) {} }");
|
||||||
ASSERT_EQUALS("[test.cpp:1]: (style) Parameter 'p' can be declared with const\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:1]: (style) Parameter 'p' can be declared as pointer to const\n", errout.str());
|
||||||
|
|
||||||
check("void foo(int *p) { return *p + 1; }");
|
check("void foo(int *p) { return *p + 1; }");
|
||||||
ASSERT_EQUALS("[test.cpp:1]: (style) Parameter 'p' can be declared with const\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:1]: (style) Parameter 'p' can be declared as pointer to const\n", errout.str());
|
||||||
|
|
||||||
check("void foo(int *p) { return *p > 1; }");
|
check("void foo(int *p) { return *p > 1; }");
|
||||||
ASSERT_EQUALS("[test.cpp:1]: (style) Parameter 'p' can be declared with const\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:1]: (style) Parameter 'p' can be declared as pointer to const\n", errout.str());
|
||||||
|
|
||||||
check("void foo(const int* c) { if (c == 0) {}; }");
|
check("void foo(const int* c) { if (c == 0) {}; }");
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
@ -3002,14 +3002,14 @@ private:
|
||||||
" static int i[1] = {};\n"
|
" static int i[1] = {};\n"
|
||||||
" return i[0];\n"
|
" return i[0];\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS("[test.cpp:2]: (style) Variable 'i' can be declared with const\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:2]: (style) Variable 'i' can be declared as const array\n", errout.str());
|
||||||
|
|
||||||
check("int f() {\n"
|
check("int f() {\n"
|
||||||
" static int i[] = { 0 };\n"
|
" static int i[] = { 0 };\n"
|
||||||
" int j = i[0] + 1;\n"
|
" int j = i[0] + 1;\n"
|
||||||
" return j;\n"
|
" return j;\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS("[test.cpp:2]: (style) Variable 'i' can be declared with const\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:2]: (style) Variable 'i' can be declared as const array\n", errout.str());
|
||||||
|
|
||||||
// #10471
|
// #10471
|
||||||
check("void f(std::array<int, 1> const& i) {\n"
|
check("void f(std::array<int, 1> const& i) {\n"
|
||||||
|
@ -3032,7 +3032,7 @@ private:
|
||||||
" for (const auto* p : v)\n"
|
" for (const auto* p : v)\n"
|
||||||
" if (p == nullptr) {}\n"
|
" if (p == nullptr) {}\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS("[test.cpp:1]: (style) Parameter 'v' can be declared with const\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:1]: (style) Parameter 'v' can be declared as reference 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"
|
||||||
|
@ -3040,7 +3040,7 @@ private:
|
||||||
" for (const auto* p : v)\n"
|
" for (const auto* p : v)\n"
|
||||||
" if (p == nullptr) {}\n"
|
" if (p == nullptr) {}\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS("[test.cpp:1]: (style) Parameter 'v' can be declared with const\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:1]: (style) Parameter 'v' can be declared as reference to const\n", errout.str());
|
||||||
|
|
||||||
check("void f(const std::vector<const int*>& v) {\n"
|
check("void f(const std::vector<const int*>& v) {\n"
|
||||||
" for (const auto& p : v)\n"
|
" for (const auto& p : v)\n"
|
||||||
|
@ -3078,9 +3078,33 @@ private:
|
||||||
" tmp = b[i];\n"
|
" tmp = b[i];\n"
|
||||||
" printf(\"%s\", tmp);\n"
|
" printf(\"%s\", tmp);\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'a' can be declared with const\n"
|
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'a' can be declared as const array\n"
|
||||||
"[test.cpp:4]: (style) Variable 'b' can be declared with const\n",
|
"[test.cpp:4]: (style) Variable 'b' can be declared as const array\n",
|
||||||
errout.str());
|
errout.str());
|
||||||
|
|
||||||
|
check("typedef void* HWND;\n"
|
||||||
|
"void f(const HWND h) {\n"
|
||||||
|
" if (h == nullptr) {}\n"
|
||||||
|
"}\n");
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
check("using HWND = void*;\n"
|
||||||
|
"void f(const HWND h) {\n"
|
||||||
|
" if (h == nullptr) {}\n"
|
||||||
|
"}\n");
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
check("typedef int A;\n"
|
||||||
|
"void f(A* x) {\n"
|
||||||
|
" if (x == nullptr) {}\n"
|
||||||
|
"}\n");
|
||||||
|
ASSERT_EQUALS("[test.cpp:2]: (style) Parameter 'x' can be declared as pointer to const\n", errout.str());
|
||||||
|
|
||||||
|
check("using A = int;\n"
|
||||||
|
"void f(A* x) {\n"
|
||||||
|
" if (x == nullptr) {}\n"
|
||||||
|
"}\n");
|
||||||
|
ASSERT_EQUALS("[test.cpp:2]: (style) Parameter 'x' can be declared as pointer to const\n", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void switchRedundantAssignmentTest() {
|
void switchRedundantAssignmentTest() {
|
||||||
|
@ -5254,7 +5278,7 @@ private:
|
||||||
|
|
||||||
// #5535: Reference named like its type
|
// #5535: Reference named like its type
|
||||||
check("void foo() { UMSConfig& UMSConfig = GetUMSConfiguration(); }");
|
check("void foo() { UMSConfig& UMSConfig = GetUMSConfiguration(); }");
|
||||||
ASSERT_EQUALS("[test.cpp:1]: (style) Variable 'UMSConfig' can be declared with const\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:1]: (style) Variable 'UMSConfig' can be declared as reference to const\n", errout.str());
|
||||||
|
|
||||||
// #3868 - false positive (same expression on both sides of |)
|
// #3868 - false positive (same expression on both sides of |)
|
||||||
check("void f(int x) {\n"
|
check("void f(int x) {\n"
|
||||||
|
@ -9280,7 +9304,7 @@ private:
|
||||||
" int local_argc = 0;\n"
|
" int local_argc = 0;\n"
|
||||||
" local_argv[local_argc++] = argv[0];\n"
|
" local_argv[local_argc++] = argv[0];\n"
|
||||||
"}\n", "test.c");
|
"}\n", "test.c");
|
||||||
ASSERT_EQUALS("[test.c:1]: (style) Parameter 'argv' can be declared with const\n", errout.str());
|
ASSERT_EQUALS("[test.c:1]: (style) Parameter 'argv' can be declared as const array\n", errout.str());
|
||||||
|
|
||||||
check("void f() {\n"
|
check("void f() {\n"
|
||||||
" int x = 0;\n"
|
" int x = 0;\n"
|
||||||
|
|
|
@ -7744,6 +7744,7 @@ private:
|
||||||
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"));
|
||||||
|
ASSERT_EQUALS("void * const", typeOf("typedef void* HWND; const HWND x = 0;", "x"));
|
||||||
|
|
||||||
// Variable declaration
|
// Variable declaration
|
||||||
ASSERT_EQUALS("char *", typeOf("; char abc[] = \"abc\";", "["));
|
ASSERT_EQUALS("char *", typeOf("; char abc[] = \"abc\";", "["));
|
||||||
|
|
|
@ -151,6 +151,7 @@ private:
|
||||||
TEST_CASE(localvaralias17); // ticket #8911
|
TEST_CASE(localvaralias17); // ticket #8911
|
||||||
TEST_CASE(localvaralias18); // ticket #9234 - iterator
|
TEST_CASE(localvaralias18); // ticket #9234 - iterator
|
||||||
TEST_CASE(localvaralias19); // ticket #9828
|
TEST_CASE(localvaralias19); // ticket #9828
|
||||||
|
TEST_CASE(localvaralias20); // ticket #10966
|
||||||
TEST_CASE(localvarasm);
|
TEST_CASE(localvarasm);
|
||||||
TEST_CASE(localvarstatic);
|
TEST_CASE(localvarstatic);
|
||||||
TEST_CASE(localvarextern);
|
TEST_CASE(localvarextern);
|
||||||
|
@ -4674,6 +4675,21 @@ private:
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void localvaralias20() { // #10966
|
||||||
|
functionVariableUsage("struct A {};\n"
|
||||||
|
"A g();\n"
|
||||||
|
"void f() {\n"
|
||||||
|
" const auto& a = g();\n"
|
||||||
|
" const auto& b = a;\n"
|
||||||
|
" const auto&& c = g();\n"
|
||||||
|
" auto&& d = c;\n"
|
||||||
|
"}\n");
|
||||||
|
TODO_ASSERT_EQUALS("[test.cpp:5]: (style) Variable 'b' is assigned a value that is never used.\n"
|
||||||
|
"[test.cpp:7]: (style) Variable 'd' is assigned a value that is never used.\n",
|
||||||
|
"[test.cpp:7]: (style) Variable 'd' is assigned a value that is never used.\n",
|
||||||
|
errout.str());
|
||||||
|
}
|
||||||
|
|
||||||
void localvarasm() {
|
void localvarasm() {
|
||||||
|
|
||||||
functionVariableUsage("void foo(int &b)\n"
|
functionVariableUsage("void foo(int &b)\n"
|
||||||
|
|
Loading…
Reference in New Issue