Skip to content

Commit 523c41a

Browse files
Fix #11978 debug: Executable scope 'x' with unknown function. (#5437)
1 parent 5eb1750 commit 523c41a

2 files changed

Lines changed: 36 additions & 6 deletions

File tree

lib/tokenize.cpp

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1673,7 +1673,7 @@ void Tokenizer::simplifyTypedefCpp()
16731673
}
16741674

16751675
// check for member functions
1676-
else if (isCPP() && tok2->str() == "(" && isFunctionHead(tok2, "{")) {
1676+
else if (isCPP() && tok2->str() == "(" && isFunctionHead(tok2, "{:")) {
16771677
const Token *func = tok2->previous();
16781678

16791679
/** @todo add support for multi-token operators */
@@ -4878,6 +4878,24 @@ static Token * matchMemberFunctionName(const Member &func, const std::list<Scope
48784878
return Token::Match(tok, "~| %name% (") ? tok : nullptr;
48794879
}
48804880

4881+
template<typename T>
4882+
static T* skipInitializerList(T* tok)
4883+
{
4884+
T* const start = tok;
4885+
while (Token::Match(tok, "[:,] ::| %name%")) {
4886+
tok = tok->tokAt(tok->strAt(1) == "::" ? 1 : 2);
4887+
while (Token::Match(tok, ":: %name%"))
4888+
tok = tok->tokAt(2);
4889+
if (!Token::Match(tok, "[({<]") || !tok->link())
4890+
return start;
4891+
const bool isTemplate = tok->str() == "<";
4892+
tok = tok->link()->next();
4893+
if (isTemplate && tok && tok->link())
4894+
tok = tok->link()->next();
4895+
}
4896+
return tok;
4897+
}
4898+
48814899
void Tokenizer::setVarIdPass2()
48824900
{
48834901
std::map<nonneg int, std::map<std::string, nonneg int>> structMembers;
@@ -5042,8 +5060,8 @@ void Tokenizer::setVarIdPass2()
50425060
tok2 = tok2->link();
50435061

50445062
// Skip initialization list
5045-
while (Token::Match(tok2, ") [:,] %name% ("))
5046-
tok2 = tok2->linkAt(3);
5063+
if (Token::simpleMatch(tok2, ") :"))
5064+
tok2 = skipInitializerList(tok2->next());
50475065
}
50485066
}
50495067

@@ -8637,9 +8655,7 @@ void Tokenizer::simplifyFunctionTryCatch()
86378655
if (!isFunctionHead(tok->previous(), "try"))
86388656
continue;
86398657

8640-
Token* tryStartToken = tok->next();
8641-
while (Token::Match(tryStartToken, "[:,] %name% (|{")) // skip init list
8642-
tryStartToken = tryStartToken->linkAt(2)->next();
8658+
Token* tryStartToken = skipInitializerList(tok->next());
86438659

86448660
if (!Token::simpleMatch(tryStartToken, "{"))
86458661
syntaxError(tryStartToken, "Invalid function-try-catch block code. Did not find '{' for try body.");

test/testsimplifytypedef.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,7 @@ class TestSimplifyTypedef : public TestFixture {
210210
TEST_CASE(simplifyTypedef143); // #11506
211211
TEST_CASE(simplifyTypedef144); // #9353
212212
TEST_CASE(simplifyTypedef145); // #9353
213+
TEST_CASE(simplifyTypedef146);
213214

214215
TEST_CASE(simplifyTypedefFunction1);
215216
TEST_CASE(simplifyTypedefFunction2); // ticket #1685
@@ -3365,6 +3366,19 @@ class TestSimplifyTypedef : public TestFixture {
33653366
ASSERT_EQUALS("void g ( ) { sizeof ( t ) ; }", tok(code)); // TODO: handle implicit int
33663367
}
33673368

3369+
void simplifyTypedef146() {
3370+
const char* code{};
3371+
code = "namespace N {\n" // #11978
3372+
" typedef int T;\n"
3373+
" struct C {\n"
3374+
" C(T*);\n"
3375+
" void* p;\n"
3376+
" };\n"
3377+
"}\n"
3378+
"N::C::C(T*) : p(nullptr) {}\n";
3379+
ASSERT_EQUALS("namespace N { struct C { C ( int * ) ; void * p ; } ; } N :: C :: C ( int * ) : p ( nullptr ) { }", tok(code));
3380+
}
3381+
33683382
void simplifyTypedefFunction1() {
33693383
{
33703384
const char code[] = "typedef void (*my_func)();\n"

0 commit comments

Comments
 (0)