From 047b6086ddac3d9c60c743b5d6d0646325b478f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Fri, 26 Apr 2024 15:21:34 +0200 Subject: [PATCH] Fix #12660 (Tokenizer::setVarId: varid is wrongly set for argument name that shadows method name) (#6347) --- lib/tokenize.cpp | 7 ++++++- test/testvarid.cpp | 24 ++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index f03cf667fe1..8655fe59dca 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -99,6 +99,10 @@ const Token * Tokenizer::isFunctionHead(const Token *tok, const std::string &end return nullptr; if (tok->str() == "(") tok = tok->link(); + if (tok->str() != ")") + return nullptr; + if (!tok->isCpp() && !Token::Match(tok->link()->previous(), "%name%|)")) + return nullptr; if (Token::Match(tok, ") ;|{|[")) { tok = tok->next(); while (tok && tok->str() == "[" && tok->link()) { @@ -131,7 +135,8 @@ const Token * Tokenizer::isFunctionHead(const Token *tok, const std::string &end tok = tok->next(); if (Token::Match(tok, "= 0|default|delete ;")) tok = tok->tokAt(2); - + if (tok && tok->str() == ":" && !Token::Match(tok->next(), "%name%|::")) + return nullptr; return (tok && endsWith.find(tok->str()) != std::string::npos) ? tok : nullptr; } return nullptr; diff --git a/test/testvarid.cpp b/test/testvarid.cpp index d6d8ab03c7d..47a782475b0 100644 --- a/test/testvarid.cpp +++ b/test/testvarid.cpp @@ -101,6 +101,7 @@ class TestVarID : public TestFixture { TEST_CASE(varid67); // #11711 - NOT function pointer TEST_CASE(varid68); // #11740 - switch (str_chars(&strOut)[0]) TEST_CASE(varid69); + TEST_CASE(varid70); // #12660 - function TEST_CASE(varid_for_1); TEST_CASE(varid_for_2); TEST_CASE(varid_cpp_keywords_in_c_code); @@ -1270,6 +1271,29 @@ class TestVarID : public TestFixture { ASSERT_EQUALS(expected1, tokenize(code1, true)); } + void varid70() { + // isFunctionHead + const char code1[] = "int x = 1 ? (1 << 0) : 0;\n" + "void foo(bool init);\n" + "void init();\n"; + const char expected1[] = "1: int x@1 ; x@1 = 1 ? ( 1 << 0 ) : 0 ;\n" + "2: void foo ( bool init@2 ) ;\n" + "3: void init ( ) ;\n"; + ASSERT_EQUALS(expected1, tokenize(code1, true)); + + const char code2[] = "int x = 1 ? f(1 << 0) : 0;\n" + "void foo(bool init);\n" + "void init();\n"; + const char expected2[] = "1: int x@1 ; x@1 = 1 ? f ( 1 << 0 ) : 0 ;\n" + "2: void foo ( bool init@2 ) ;\n" + "3: void init ( ) ;\n"; + ASSERT_EQUALS(expected2, tokenize(code2, true)); + + const char code3[] = "extern void (*arr[10])(uint32_t some);\n"; + const char expected3[] = "1: extern void ( * arr@1 [ 10 ] ) ( uint32_t some@2 ) ;\n"; + ASSERT_EQUALS(expected3, tokenize(code3, true)); + } + void varid_for_1() { const char code[] = "void foo(int a, int b) {\n" " for (int a=1,b=2;;) {}\n"