From 17ea101e7bd19556e3b7651210068e20dc8b9fee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Thu, 19 Oct 2023 21:02:03 +0200 Subject: [PATCH] Fix #12081 (Tokenizer::simplifyTypedef: Handle volatile structs better) (#5577) --- lib/tokenize.cpp | 21 +++++++++++---------- test/testsimplifytypedef.cpp | 16 ++++++++++++++++ 2 files changed, 27 insertions(+), 10 deletions(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 9e9749a4f..6f82c551d 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -410,17 +410,15 @@ namespace { static Token *splitDefinitionFromTypedef(Token *tok, nonneg int *unnamedCount) { std::string name; - bool isConst = false; - Token *tok1 = tok->next(); + std::set qualifiers; - // skip const if present - if (tok1->str() == "const") { - tok1->deleteThis(); - isConst = true; + while (Token::Match(tok->next(), "const|volatile")) { + qualifiers.insert(tok->next()->str()); + tok->deleteNext(); } // skip "class|struct|union|enum" - tok1 = tok1->next(); + Token *tok1 = tok->tokAt(2); const bool hasName = Token::Match(tok1, "%name%"); @@ -465,8 +463,8 @@ static Token *splitDefinitionFromTypedef(Token *tok, nonneg int *unnamedCount) tok1->insertToken("typedef"); tok1 = tok1->next(); Token * tok3 = tok1; - if (isConst) { - tok1->insertToken("const"); + for (const std::string &qualifier : qualifiers) { + tok1->insertToken(qualifier); tok1 = tok1->next(); } tok1->insertToken(tok->next()->str()); // struct, union or enum @@ -1209,7 +1207,10 @@ void Tokenizer::simplifyTypedefCpp() // pull struct, union, enum or class definition out of typedef // use typedef name for unnamed struct, union, enum or class - if (Token::Match(tok->next(), "const| struct|enum|union|class %type%| {|:")) { + const Token* tokClass = tok->next(); + while (Token::Match(tokClass, "const|volatile")) + tokClass = tokClass->next(); + if (Token::Match(tokClass, "struct|enum|union|class %type%| {|:")) { Token *tok1 = splitDefinitionFromTypedef(tok, &mUnnamedCount); if (!tok1) continue; diff --git a/test/testsimplifytypedef.cpp b/test/testsimplifytypedef.cpp index e845fa7da..1239ddbda 100644 --- a/test/testsimplifytypedef.cpp +++ b/test/testsimplifytypedef.cpp @@ -222,6 +222,8 @@ private: TEST_CASE(simplifyTypedefFunction9); TEST_CASE(simplifyTypedefFunction10); // #5191 + TEST_CASE(simplifyTypedefStruct); // #12081 - volatile struct + TEST_CASE(simplifyTypedefShadow); // #4445 - shadow variable TEST_CASE(simplifyTypedefMacro); @@ -4002,6 +4004,20 @@ private: tok(code,false)); } + void simplifyTypedefStruct() { + const char code1[] = "typedef struct S { int x; } xyz;\n" + "xyz var;"; + ASSERT_EQUALS("struct S { int x ; } ; struct S var ;", tok(code1,false)); + + const char code2[] = "typedef const struct S { int x; } xyz;\n" + "xyz var;"; + ASSERT_EQUALS("struct S { int x ; } ; const struct S var ;", tok(code2,false)); + + const char code3[] = "typedef volatile struct S { int x; } xyz;\n" + "xyz var;"; + ASSERT_EQUALS("struct S { int x ; } ; volatile struct S var ;", tok(code3,false)); + } + void simplifyTypedefShadow() { // shadow variable (#4445) const char code[] = "typedef struct { int x; } xyz;;\n" "void f(){\n"