Maybeunusedsupport (#2570)
* Add rudimentary support for [[maybe_unused]] * Add more test cases. use the symboldatabase rather than reparsing. Fix travis error. * test review actions * change var to usage._var
This commit is contained in:
parent
97f5c5767e
commit
82c09f243b
|
@ -1246,7 +1246,8 @@ void CheckUnusedVar::checkFunctionVariableUsage()
|
|||
}
|
||||
|
||||
// warn
|
||||
unreadVariableError(tok, expr->expressionString(), false);
|
||||
if(!expr->variable() || !expr->variable()->isMaybeUnused())
|
||||
unreadVariableError(tok, expr->expressionString(), false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1281,9 +1282,11 @@ void CheckUnusedVar::checkFunctionVariableUsage()
|
|||
allocatedButUnusedVariableError(usage._lastAccess, varname);
|
||||
|
||||
// variable has not been written, read, or modified
|
||||
else if (usage.unused() && !usage._modified)
|
||||
unusedVariableError(usage._var->nameToken(), varname);
|
||||
|
||||
else if (usage.unused() && !usage._modified) {
|
||||
if (!usage._var->isMaybeUnused()) {
|
||||
unusedVariableError(usage._var->nameToken(), varname);
|
||||
}
|
||||
}
|
||||
// variable has not been written but has been modified
|
||||
else if (usage._modified && !usage._write && !usage._allocateMemory && var && !var->isStlType())
|
||||
unassignedVariableError(usage._var->nameToken(), varname);
|
||||
|
|
|
@ -1889,6 +1889,10 @@ void Variable::evaluate(const Settings* settings)
|
|||
setFlag(fIsReference, true); // Set also fIsReference
|
||||
}
|
||||
|
||||
if (tok->isMaybeUnused()) {
|
||||
setFlag(fIsMaybeUnused, true);
|
||||
}
|
||||
|
||||
if (tok->str() == "<" && tok->link())
|
||||
tok = tok->link();
|
||||
else
|
||||
|
|
|
@ -193,7 +193,8 @@ class CPPCHECKLIB Variable {
|
|||
fIsStlString = (1 << 11), /** @brief std::string|wstring|basic_string<T>|u16string|u32string */
|
||||
fIsFloatType = (1 << 12), /** @brief Floating point type */
|
||||
fIsVolatile = (1 << 13), /** @brief volatile */
|
||||
fIsSmartPointer = (1 << 14) /** @brief std::shared_ptr|unique_ptr */
|
||||
fIsSmartPointer = (1 << 14),/** @brief std::shared_ptr|unique_ptr */
|
||||
fIsMaybeUnused = (1 << 15), /** @brief marked [[maybe_unused]] */
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -618,6 +619,10 @@ public:
|
|||
return type() && type()->isEnumType();
|
||||
}
|
||||
|
||||
bool isMaybeUnused() const {
|
||||
return getFlag(fIsMaybeUnused);
|
||||
}
|
||||
|
||||
const ValueType *valueType() const {
|
||||
return mValueType;
|
||||
}
|
||||
|
|
|
@ -541,6 +541,12 @@ public:
|
|||
void isAttributeNodiscard(const bool value) {
|
||||
setFlag(fIsAttributeNodiscard, value);
|
||||
}
|
||||
bool isMaybeUnused() const {
|
||||
return getFlag(fIsMaybeUnused);
|
||||
}
|
||||
void isMaybeUnused(const bool value) {
|
||||
setFlag(fIsMaybeUnused, value);
|
||||
}
|
||||
void setCppcheckAttribute(TokenImpl::CppcheckAttributes::Type type, MathLib::bigint value) {
|
||||
mImpl->setCppcheckAttribute(type, value);
|
||||
}
|
||||
|
@ -1155,6 +1161,7 @@ private:
|
|||
fIncompleteVar = (1 << 25),
|
||||
fConstexpr = (1 << 26),
|
||||
fExternC = (1 << 27),
|
||||
fIsMaybeUnused = (1 << 28), // [[maybe_unsed]]
|
||||
};
|
||||
|
||||
Token::Type mTokType;
|
||||
|
|
|
@ -10246,6 +10246,11 @@ void Tokenizer::simplifyCPPAttribute()
|
|||
else
|
||||
head->previous()->isAttributeNodiscard(true);
|
||||
}
|
||||
} else if (Token::simpleMatch(tok->tokAt(2), "maybe_unused")) {
|
||||
Token* head = tok->tokAt(5);
|
||||
while (isCPPAttribute(head))
|
||||
head = head->tokAt(5);
|
||||
head->isMaybeUnused(true);
|
||||
} else if (Token::Match(tok->previous(), ") [ [ expects|ensures|assert default|audit|axiom| : %name% <|<=|>|>= %num% ] ]")) {
|
||||
const Token *vartok = tok->tokAt(4);
|
||||
if (vartok->str() == ":")
|
||||
|
|
|
@ -148,6 +148,7 @@ private:
|
|||
TEST_CASE(localvarconst1);
|
||||
TEST_CASE(localvarconst2);
|
||||
TEST_CASE(localvarreturn); // ticket #9167
|
||||
TEST_CASE(localvarmaybeunused);
|
||||
|
||||
TEST_CASE(localvarthrow); // ticket #3687
|
||||
|
||||
|
@ -4160,6 +4161,87 @@ private:
|
|||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
void localvarmaybeunused() {
|
||||
functionVariableUsage("int main() {\n"
|
||||
" [[maybe_unused]] int x;\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
functionVariableUsage("[[nodiscard]] int getX() { return 4; }\n"
|
||||
"int main() {\n"
|
||||
" [[maybe_unused]] int x = getX();\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
functionVariableUsage("[[nodiscard]] int getX() { return 4; }\n"
|
||||
"int main() {\n"
|
||||
" [[maybe_unused]] int x = getX();\n"
|
||||
" x = getX();\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
functionVariableUsage("[[nodiscard]] int getX() { return 4; }\n"
|
||||
"int main() {\n"
|
||||
" [[maybe_unused]] int x = getX();\n"
|
||||
" x = getX();\n"
|
||||
" std::cout << x;\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
functionVariableUsage("int main() {\n"
|
||||
" [[maybe_unused]] const int x = getX();\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
functionVariableUsage("int main() {\n"
|
||||
" [[maybe_unused]] const int& x = getX();\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
functionVariableUsage("int main() {\n"
|
||||
" [[maybe_unused]] const int* x = getX();\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
functionVariableUsage("int main() {\n"
|
||||
" [[maybe_unused]] int& x = getX();\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
functionVariableUsage("int main() {\n"
|
||||
" [[maybe_unused]] int* x = getX();\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
functionVariableUsage("int main() {\n"
|
||||
" [[maybe_unused]] auto x = getX();\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
functionVariableUsage("int main() {\n"
|
||||
" [[maybe_unused]] auto&& x = getX();\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
functionVariableUsage("int main() {\n"
|
||||
" [[maybe_unused]] int x[] = getX();\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
functionVariableUsage("int main() {\n"
|
||||
" [[maybe_unused]] constexpr volatile static int x = 1;\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
functionVariableUsage("[[maybe_unused]] inline int x = 1;");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
functionVariableUsage("int main() {\n"
|
||||
" [[maybe_unused]] [[anotherattribute]] const int* = 1;\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
void localvarthrow() { // ticket #3687
|
||||
functionVariableUsage("void foo() {\n"
|
||||
" try {}"
|
||||
|
|
Loading…
Reference in New Issue