Fixed #9707 (False positive: unreadVariable, union)
This commit is contained in:
parent
b19e631292
commit
6de91d6386
|
@ -1231,6 +1231,10 @@ void CheckUnusedVar::checkFunctionVariableUsage()
|
||||||
if (op1Var->nameToken()->isAttributeUnused())
|
if (op1Var->nameToken()->isAttributeUnused())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
// Avoid FP for union..
|
||||||
|
if (op1Var->type() && op1Var->type()->isUnionType())
|
||||||
|
continue;
|
||||||
|
|
||||||
// Bailout for unknown template classes, we have no idea what side effects such assignments have
|
// Bailout for unknown template classes, we have no idea what side effects such assignments have
|
||||||
if (mTokenizer->isCPP() &&
|
if (mTokenizer->isCPP() &&
|
||||||
op1Var->isClass() &&
|
op1Var->isClass() &&
|
||||||
|
|
|
@ -2818,6 +2818,26 @@ void SymbolDatabase::addNewFunction(Scope **scope, const Token **tok)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Type::isClassType() const
|
||||||
|
{
|
||||||
|
return classScope && classScope->type == Scope::ScopeType::eClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Type::isEnumType() const
|
||||||
|
{
|
||||||
|
return classScope && classScope->type == Scope::ScopeType::eEnum;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Type::isStructType() const
|
||||||
|
{
|
||||||
|
return classScope && classScope->type == Scope::ScopeType::eStruct;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Type::isUnionType() const
|
||||||
|
{
|
||||||
|
return classScope && classScope->type == Scope::ScopeType::eUnion;
|
||||||
|
}
|
||||||
|
|
||||||
const Token *Type::initBaseInfo(const Token *tok, const Token *tok1)
|
const Token *Type::initBaseInfo(const Token *tok, const Token *tok1)
|
||||||
{
|
{
|
||||||
// goto initial '{'
|
// goto initial '{'
|
||||||
|
|
|
@ -131,22 +131,15 @@ public:
|
||||||
return classDef ? classDef->str() : emptyString;
|
return classDef ? classDef->str() : emptyString;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isClassType() const {
|
bool isClassType() const;
|
||||||
return classDef && classDef->str() == "class";
|
bool isEnumType() const;
|
||||||
}
|
bool isStructType() const;
|
||||||
|
bool isUnionType() const;
|
||||||
bool isEnumType() const {
|
|
||||||
return classDef && classDef->str() == "enum";
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isTypeAlias() const {
|
bool isTypeAlias() const {
|
||||||
return classDef && classDef->str() == "using";
|
return classDef && classDef->str() == "using";
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isStructType() const {
|
|
||||||
return classDef && classDef->str() == "struct";
|
|
||||||
}
|
|
||||||
|
|
||||||
const Token *initBaseInfo(const Token *tok, const Token *tok1);
|
const Token *initBaseInfo(const Token *tok, const Token *tok1);
|
||||||
|
|
||||||
const Function* getFunction(const std::string& funcName) const;
|
const Function* getFunction(const std::string& funcName) const;
|
||||||
|
|
|
@ -171,6 +171,7 @@ private:
|
||||||
TEST_CASE(localvarStruct8);
|
TEST_CASE(localvarStruct8);
|
||||||
TEST_CASE(localvarStruct9);
|
TEST_CASE(localvarStruct9);
|
||||||
TEST_CASE(localvarStructArray);
|
TEST_CASE(localvarStructArray);
|
||||||
|
TEST_CASE(localvarUnion1);
|
||||||
|
|
||||||
TEST_CASE(localvarOp); // Usage with arithmetic operators
|
TEST_CASE(localvarOp); // Usage with arithmetic operators
|
||||||
TEST_CASE(localvarInvert); // Usage with inverted variable
|
TEST_CASE(localvarInvert); // Usage with inverted variable
|
||||||
|
@ -3625,6 +3626,18 @@ private:
|
||||||
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'x[0].a' is assigned a value that is never used.\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'x[0].a' is assigned a value that is never used.\n", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void localvarUnion1() {
|
||||||
|
// #9707
|
||||||
|
functionVariableUsage("static short read(FILE *fp) {\n"
|
||||||
|
" typedef union { short s; unsigned char c[2]; } u;\n"
|
||||||
|
" u x;\n"
|
||||||
|
" x.c[0] = fgetuc(fp);\n"
|
||||||
|
" x.c[1] = fgetuc(fp);\n"
|
||||||
|
" return x.s;\n"
|
||||||
|
"}");
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
}
|
||||||
|
|
||||||
void localvarOp() {
|
void localvarOp() {
|
||||||
const char op[] = "+-*/%&|^";
|
const char op[] = "+-*/%&|^";
|
||||||
for (const char *p = op; *p; ++p) {
|
for (const char *p = op; *p; ++p) {
|
||||||
|
|
Loading…
Reference in New Issue