Fix #11408 debug: Function::addArguments found argument 't' with varid 0 (#5507)

This commit is contained in:
chrchr-github 2023-10-05 10:01:46 +02:00 committed by GitHub
parent 354ea60b87
commit d9a8909d2a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 44 additions and 4 deletions

View File

@ -4365,9 +4365,14 @@ void Function::addArguments(const SymbolDatabase *symbolDatabase, const Scope *s
if (Token::Match(typeTok, ",|)")) { // #8333
symbolDatabase->mTokenizer.syntaxError(typeTok);
}
if (Token::Match(typeTok, "%type% <") && Token::Match(typeTok->linkAt(1), "> :: %type%"))
typeTok = typeTok->linkAt(1)->tokAt(2);
// skip over qualification
while (Token::Match(typeTok, "%type% ::"))
while (Token::Match(typeTok, "%type% ::")) {
typeTok = typeTok->tokAt(2);
if (Token::Match(typeTok, "%type% <") && Token::Match(typeTok->linkAt(1), "> :: %type%"))
typeTok = typeTok->linkAt(1)->tokAt(2);
}
// check for argument with no name or missing varid
if (!endTok) {

View File

@ -4640,6 +4640,10 @@ void Tokenizer::setVarIdPass1()
} catch (const Token * errTok) {
syntaxError(errTok);
}
if (tok->str() == "(" && isFunctionHead(tok, "{") && scopeStack.top().isExecutable)
inlineFunction = true;
if (decl) {
if (isCPP()) {
if (Token *declTypeTok = Token::findsimplematch(tok, "decltype (", tok2)) {
@ -4650,9 +4654,6 @@ void Tokenizer::setVarIdPass1()
}
}
if (tok->str() == "(" && isFunctionHead(tok,"{") && scopeStack.top().isExecutable)
inlineFunction = true;
const Token* prev2 = tok2->previous();
if (Token::Match(prev2, "%type% [;[=,)]") && tok2->previous()->str() != "const")
;

View File

@ -248,6 +248,7 @@ private:
TEST_CASE(functionArgs18); // #10376
TEST_CASE(functionArgs19); // #10376
TEST_CASE(functionArgs20);
TEST_CASE(functionArgs21);
TEST_CASE(functionImplicitlyVirtual);
TEST_CASE(functionGetOverridden);
@ -2765,6 +2766,28 @@ private:
TODO_ASSERT(arg->hasDefault());
}
void functionArgs21() {
const char code[] = "void f(std::vector<int>::size_type) {}\n" // #11408
"template<typename T>\n"
"struct S { using t = int; };\n"
"template<typename T>\n"
"S<T> operator+(const S<T>&lhs, typename S<T>::t) { return lhs; }";
GET_SYMBOL_DB(code);
ASSERT(db != nullptr);
auto it = db->functionScopes.begin();
const Function *func = (*it)->function;
ASSERT_EQUALS("f", func->name());
ASSERT_EQUALS(1, func->argCount());
const Variable* arg = func->getArgumentVar(0);
ASSERT_EQUALS("", arg->name());
++it;
func = (*it)->function;
ASSERT_EQUALS("operator+", func->name());
ASSERT_EQUALS(2, func->argCount());
arg = func->getArgumentVar(1);
ASSERT_EQUALS("", arg->name());
}
void functionImplicitlyVirtual() {
GET_SYMBOL_DB("class base { virtual void f(); };\n"
"class derived : base { void f(); };\n"

View File

@ -100,6 +100,7 @@ private:
TEST_CASE(varid66);
TEST_CASE(varid67); // #11711 - NOT function pointer
TEST_CASE(varid68); // #11740 - switch (str_chars(&strOut)[0])
TEST_CASE(varid69);
TEST_CASE(varid_for_1);
TEST_CASE(varid_for_2);
TEST_CASE(varid_cpp_keywords_in_c_code);
@ -1241,6 +1242,16 @@ private:
ASSERT_EQUALS(expected1, tokenize(code1, "test.cpp"));
}
void varid69() {
const char code1[] = "void f() {\n"
" auto g = [](int&, int& r, int i) {};\n"
"}";
const char expected1[] = "1: void f ( ) {\n"
"2: auto g@1 ; g@1 = [ ] ( int & , int & r@2 , int i@3 ) { } ;\n"
"3: }\n";
ASSERT_EQUALS(expected1, tokenize(code1, "test.cpp"));
}
void varid_for_1() {
const char code[] = "void foo(int a, int b) {\n"
" for (int a=1,b=2;;) {}\n"