From 739a1675843f95d2f9b94ceacf4e5cc03b929e53 Mon Sep 17 00:00:00 2001 From: firewave Date: Sat, 25 Jan 2025 23:43:51 +0100 Subject: [PATCH 1/2] re-added type debug validation after simplification --- lib/tokenize.cpp | 36 +++++++++++++++++++++--------------- lib/tokenize.h | 2 ++ 2 files changed, 23 insertions(+), 15 deletions(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 11a0bb066c4..d0789693bdc 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -3441,6 +3441,8 @@ bool Tokenizer::simplifyTokens1(const std::string &configuration) mSymbolDatabase->setArrayDimensionsUsingValueFlow(); } + validateTypes(); + printDebugOutput(1, std::cout); return true; @@ -5923,25 +5925,29 @@ void Tokenizer::printDebugOutput(int simplification, std::ostream &out) const if (xml) out << "" << std::endl; } +} - if (mSymbolDatabase && simplification == 2U && mSettings.debugwarnings) { - printUnknownTypes(); +void Tokenizer::validateTypes() const +{ + if (!mSymbolDatabase || !mSettings.debugwarnings) + return; - // the typeStartToken() should come before typeEndToken() - for (const Variable *var : mSymbolDatabase->variableList()) { - if (!var) - continue; + printUnknownTypes(); - const Token * typetok = var->typeStartToken(); - while (typetok && typetok != var->typeEndToken()) - typetok = typetok->next(); + // the typeStartToken() should come before typeEndToken() + for (const Variable *var : mSymbolDatabase->variableList()) { + if (!var) + continue; - if (typetok != var->typeEndToken()) { - reportError(var->typeStartToken(), - Severity::debug, - "debug", - "Variable::typeStartToken() of variable '" + var->name() + "' is not located before Variable::typeEndToken(). The location of the typeStartToken() is '" + var->typeStartToken()->str() + "' at line " + std::to_string(var->typeStartToken()->linenr())); - } + const Token * typetok = var->typeStartToken(); + while (typetok && typetok != var->typeEndToken()) + typetok = typetok->next(); + + if (typetok != var->typeEndToken()) { + reportError(var->typeStartToken(), + Severity::debug, + "debug", + "Variable::typeStartToken() of variable '" + var->name() + "' is not located before Variable::typeEndToken(). The location of the typeStartToken() is '" + var->typeStartToken()->str() + "' at line " + std::to_string(var->typeStartToken()->linenr())); } } } diff --git a/lib/tokenize.h b/lib/tokenize.h index 2a79be00efb..7486c1b863f 100644 --- a/lib/tokenize.h +++ b/lib/tokenize.h @@ -556,6 +556,8 @@ class CPPCHECKLIB Tokenizer { static bool operatorEnd(const Token * tok); + void validateTypes() const; + public: const SymbolDatabase *getSymbolDatabase() const { return mSymbolDatabase; From e5f7f76d0bcef04394f8763b3ef95c4eb461e2c4 Mon Sep 17 00:00:00 2001 From: firewave Date: Thu, 24 Apr 2025 14:00:06 +0200 Subject: [PATCH 2/2] removed type debug validation --- lib/tokenize.cpp | 105 ------------------------------------------ lib/tokenize.h | 7 --- test/testtokenize.cpp | 21 --------- 3 files changed, 133 deletions(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index d0789693bdc..0569e8ccda1 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -3441,8 +3441,6 @@ bool Tokenizer::simplifyTokens1(const std::string &configuration) mSymbolDatabase->setArrayDimensionsUsingValueFlow(); } - validateTypes(); - printDebugOutput(1, std::cout); return true; @@ -5927,31 +5925,6 @@ void Tokenizer::printDebugOutput(int simplification, std::ostream &out) const } } -void Tokenizer::validateTypes() const -{ - if (!mSymbolDatabase || !mSettings.debugwarnings) - return; - - printUnknownTypes(); - - // the typeStartToken() should come before typeEndToken() - for (const Variable *var : mSymbolDatabase->variableList()) { - if (!var) - continue; - - const Token * typetok = var->typeStartToken(); - while (typetok && typetok != var->typeEndToken()) - typetok = typetok->next(); - - if (typetok != var->typeEndToken()) { - reportError(var->typeStartToken(), - Severity::debug, - "debug", - "Variable::typeStartToken() of variable '" + var->name() + "' is not located before Variable::typeEndToken(). The location of the typeStartToken() is '" + var->typeStartToken()->str() + "' at line " + std::to_string(var->typeStartToken()->linenr())); - } - } -} - void Tokenizer::dump(std::ostream &out) const { // Create a xml data dump. @@ -10581,84 +10554,6 @@ void Tokenizer::removeUnnecessaryQualification() } } -void Tokenizer::printUnknownTypes() const -{ - if (!mSymbolDatabase) - return; - - std::vector> unknowns; - - for (int i = 1; i <= mVarId; ++i) { - const Variable *var = mSymbolDatabase->getVariableFromVarId(i); - if (!var) - continue; - // is unknown type? - if (var->type() || var->typeStartToken()->isStandardType()) - continue; - - std::string name; - const Token * nameTok; - - // single token type? - if (var->typeStartToken() == var->typeEndToken()) { - nameTok = var->typeStartToken(); - name = nameTok->str(); - } - - // complicated type - else { - const Token *tok = var->typeStartToken(); - int level = 0; - - nameTok = tok; - - while (tok) { - // skip pointer and reference part of type - if (level == 0 && Token::Match(tok, "*|&")) - break; - - name += tok->str(); - - if (Token::Match(tok, "struct|union|enum")) - name += " "; - - // pointers and references are OK in template - else if (tok->str() == "<") - ++level; - else if (tok->str() == ">") - --level; - - if (tok == var->typeEndToken()) - break; - - tok = tok->next(); - } - } - - unknowns.emplace_back(std::move(name), nameTok); - } - - if (!unknowns.empty()) { - std::string last; - int count = 0; - - for (auto it = unknowns.cbegin(); it != unknowns.cend(); ++it) { - // skip types is std namespace because they are not interesting - if (it->first.find("std::") != 0) { - if (it->first != last) { - last = it->first; - count = 1; - reportError(it->second, Severity::debug, "debug", "Unknown type \'" + it->first + "\'."); - } else { - if (count < 3) // limit same type to 3 - reportError(it->second, Severity::debug, "debug", "Unknown type \'" + it->first + "\'."); - count++; - } - } - } - } -} - void Tokenizer::prepareTernaryOpForAST() { // http://en.cppreference.com/w/cpp/language/operator_precedence says about ternary operator: diff --git a/lib/tokenize.h b/lib/tokenize.h index 7486c1b863f..50bd0018b76 100644 --- a/lib/tokenize.h +++ b/lib/tokenize.h @@ -546,18 +546,11 @@ class CPPCHECKLIB Tokenizer { std::map>& structMembers, nonneg int &varId_); - /** - * Output list of unknown types. - */ - void printUnknownTypes() const; - /** Find end of SQL (or PL/SQL) block */ static const Token *findSQLBlockEnd(const Token *tokSQLStart); static bool operatorEnd(const Token * tok); - void validateTypes() const; - public: const SymbolDatabase *getSymbolDatabase() const { return mSymbolDatabase; diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index 00952138a17..b432bdd6c87 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -432,8 +432,6 @@ class TestTokenizer : public TestFixture { // --check-config TEST_CASE(checkConfiguration); - TEST_CASE(unknownType); // #8952 - TEST_CASE(unknownMacroBeforeReturn); TEST_CASE(cppcast); @@ -7917,25 +7915,6 @@ class TestTokenizer : public TestFixture { "There is an unknown macro here somewhere. Configuration is required. If DEBUG is a macro then please configure it."); } - void unknownType() { // #8952 - const Settings settings = settingsBuilder().debugwarnings().build(); - - char code[] = "class A {\n" - "public:\n" - " enum Type { Null };\n" - "};\n" - "using V = A;\n" - "V::Type value;"; - - // Tokenize.. - SimpleTokenizer tokenizer(settings, *this); - ASSERT(tokenizer.tokenize(code)); - - tokenizer.printUnknownTypes(); - - ASSERT_EQUALS("", errout_str()); - } - void unknownMacroBeforeReturn() { ASSERT_THROW_INTERNAL(tokenizeAndStringify("int f() { X return 0; }"), UNKNOWN_MACRO); }