Suppress unused struct members from types expanded from macros (#5087)

This commit is contained in:
Anton Lindqvist 2023-05-26 17:48:49 +02:00 committed by GitHub
parent 10b55cc0cf
commit 96c6276ce7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 35 additions and 0 deletions

View File

@ -1443,6 +1443,9 @@ void CheckUnusedVar::checkStructMemberUsage()
if (scope.bodyStart->fileIndex() != 0 || scope.className.empty()) if (scope.bodyStart->fileIndex() != 0 || scope.className.empty())
continue; continue;
if (scope.classDef->isExpandedMacro())
continue;
// Packed struct => possibly used by lowlevel code. Struct members might be required by hardware. // Packed struct => possibly used by lowlevel code. Struct members might be required by hardware.
if (scope.bodyEnd->isAttributePacked()) if (scope.bodyEnd->isAttributePacked())
continue; continue;

View File

@ -71,6 +71,7 @@ private:
TEST_CASE(structmember21); // #4759 TEST_CASE(structmember21); // #4759
TEST_CASE(structmember22); // #11016 TEST_CASE(structmember22); // #11016
TEST_CASE(structmember23); TEST_CASE(structmember23);
TEST_CASE(structmember_macro);
TEST_CASE(classmember); TEST_CASE(classmember);
TEST_CASE(localvar1); TEST_CASE(localvar1);
@ -272,6 +273,31 @@ private:
(checkUnusedVar.checkStructMemberUsage)(); (checkUnusedVar.checkStructMemberUsage)();
} }
void checkStructMemberUsageP(const char code[]) {
// Raw tokens..
std::vector<std::string> files(1, "test.cpp");
std::istringstream istr(code);
const simplecpp::TokenList tokens1(istr, files, files[0]);
// Preprocess..
simplecpp::TokenList tokens2(files);
std::map<std::string, simplecpp::TokenList*> filedata;
simplecpp::preprocess(tokens2, tokens1, files, filedata, simplecpp::DUI());
Preprocessor preprocessor(settings);
preprocessor.setDirectives(tokens1);
// Tokenizer..
Tokenizer tokenizer(&settings, this, &preprocessor);
tokenizer.createTokens(std::move(tokens2));
tokenizer.simplifyTokens1("");
// Check for unused variables..
CheckUnusedVar checkUnusedVar(&tokenizer, &settings, this);
(checkUnusedVar.checkStructMemberUsage)();
}
void checkFunctionVariableUsageP(const char code[], const char* filename = "test.cpp") { void checkFunctionVariableUsageP(const char code[], const char* filename = "test.cpp") {
// Raw tokens.. // Raw tokens..
std::vector<std::string> files(1, filename); std::vector<std::string> files(1, filename);
@ -1878,6 +1904,12 @@ private:
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
} }
void structmember_macro() {
checkStructMemberUsageP("#define S(n) struct n { int a, b, c; };\n"
"S(unused);\n");
ASSERT_EQUALS("", errout.str());
}
void classmember() { void classmember() {
checkStructMemberUsage("class C {\n" checkStructMemberUsage("class C {\n"
" int i{};\n" " int i{};\n"