unused struct members: don't warn about packed structs (#3088)
This commit is contained in:
parent
4d22ada078
commit
ac1a869d60
|
@ -1240,6 +1240,10 @@ void CheckUnusedVar::checkStructMemberUsage()
|
||||||
if (scope->classStart->fileIndex() != 0 || scope->className.empty())
|
if (scope->classStart->fileIndex() != 0 || scope->className.empty())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
// Packed struct => possibly used by lowlevel code. Struct members might be required by hardware.
|
||||||
|
if (scope->classEnd->isAttributePacked())
|
||||||
|
continue;
|
||||||
|
|
||||||
// Bail out if struct/union contains any functions
|
// Bail out if struct/union contains any functions
|
||||||
if (!scope->functionList.empty())
|
if (!scope->functionList.empty())
|
||||||
continue;
|
continue;
|
||||||
|
|
13
lib/token.h
13
lib/token.h
|
@ -386,6 +386,12 @@ public:
|
||||||
void isAttributeNothrow(bool value) {
|
void isAttributeNothrow(bool value) {
|
||||||
setFlag(fIsAttributeNothrow, value);
|
setFlag(fIsAttributeNothrow, value);
|
||||||
}
|
}
|
||||||
|
bool isAttributePacked() const {
|
||||||
|
return getFlag(fIsAttributePacked);
|
||||||
|
}
|
||||||
|
void isAttributePacked(bool value) {
|
||||||
|
setFlag(fIsAttributePacked, value);
|
||||||
|
}
|
||||||
bool isOperatorKeyword() const {
|
bool isOperatorKeyword() const {
|
||||||
return getFlag(fIsOperatorKeyword);
|
return getFlag(fIsOperatorKeyword);
|
||||||
}
|
}
|
||||||
|
@ -838,9 +844,10 @@ private:
|
||||||
fIsAttributeNoreturn = (1 << 12), // __attribute__((noreturn)), __declspec(noreturn)
|
fIsAttributeNoreturn = (1 << 12), // __attribute__((noreturn)), __declspec(noreturn)
|
||||||
fIsAttributeNothrow = (1 << 13), // __attribute__((nothrow)), __declspec(nothrow)
|
fIsAttributeNothrow = (1 << 13), // __attribute__((nothrow)), __declspec(nothrow)
|
||||||
fIsAttributeUsed = (1 << 14), // __attribute__((used))
|
fIsAttributeUsed = (1 << 14), // __attribute__((used))
|
||||||
fIsOperatorKeyword = (1 << 15), // operator=, etc
|
fIsAttributePacked = (1 << 15), // __attribute__((packed))
|
||||||
fIsComplex = (1 << 16), // complex/_Complex type
|
fIsOperatorKeyword = (1 << 16), // operator=, etc
|
||||||
fIsEnumType = (1 << 17) // enumeration type
|
fIsComplex = (1 << 17), // complex/_Complex type
|
||||||
|
fIsEnumType = (1 << 18) // enumeration type
|
||||||
};
|
};
|
||||||
|
|
||||||
unsigned int _flags;
|
unsigned int _flags;
|
||||||
|
|
|
@ -8585,6 +8585,10 @@ void Tokenizer::simplifyAttribute()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if (Token::simpleMatch(tok->previous(), "} __attribute__ ( ( packed )")) {
|
||||||
|
tok->previous()->isAttributePacked(true);
|
||||||
|
}
|
||||||
|
|
||||||
Token::eraseTokens(tok, tok->next()->link()->next());
|
Token::eraseTokens(tok, tok->next()->link()->next());
|
||||||
tok->deleteThis();
|
tok->deleteThis();
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,6 +48,7 @@ private:
|
||||||
TEST_CASE(structmember10);
|
TEST_CASE(structmember10);
|
||||||
TEST_CASE(structmember11); // #4168 - initialization with {} / passed by address to unknown function
|
TEST_CASE(structmember11); // #4168 - initialization with {} / passed by address to unknown function
|
||||||
TEST_CASE(structmember12); // #7179 - FP unused structmember
|
TEST_CASE(structmember12); // #7179 - FP unused structmember
|
||||||
|
TEST_CASE(structmember13); // #3088 - __attribute__((packed))
|
||||||
TEST_CASE(structmember_sizeof);
|
TEST_CASE(structmember_sizeof);
|
||||||
|
|
||||||
TEST_CASE(localvar1);
|
TEST_CASE(localvar1);
|
||||||
|
@ -422,6 +423,13 @@ private:
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void structmember13() { // #3088 - struct members required by hardware
|
||||||
|
checkStructMemberUsage("struct S {\n"
|
||||||
|
" int x;\n"
|
||||||
|
"} __attribute__((packed));");
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
}
|
||||||
|
|
||||||
void structmember_extern() {
|
void structmember_extern() {
|
||||||
// extern struct => no false positive
|
// extern struct => no false positive
|
||||||
checkStructMemberUsage("extern struct AB\n"
|
checkStructMemberUsage("extern struct AB\n"
|
||||||
|
|
Loading…
Reference in New Issue