parent
f0bc300198
commit
67eab0cd7c
|
@ -745,6 +745,8 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
|
|||
// save function prototype in database
|
||||
if (newFunc) {
|
||||
Function* func = addGlobalFunctionDecl(scope, tok, argStart, funcStart);
|
||||
if (!func)
|
||||
break;
|
||||
|
||||
if (Token::Match(argStart->link(), ") const| noexcept")) {
|
||||
int arg = 2;
|
||||
|
@ -1658,6 +1660,9 @@ Function* SymbolDatabase::addGlobalFunction(Scope*& scope, const Token*& tok, co
|
|||
if (!function)
|
||||
function = addGlobalFunctionDecl(scope, tok, argStart, funcStart);
|
||||
|
||||
if (!function)
|
||||
return 0;
|
||||
|
||||
function->arg = argStart;
|
||||
function->token = funcStart;
|
||||
function->hasBody(true);
|
||||
|
@ -1683,6 +1688,8 @@ Function* SymbolDatabase::addGlobalFunctionDecl(Scope*& scope, const Token *tok,
|
|||
function.access = Public;
|
||||
|
||||
// save the function name location
|
||||
if (funcStart && isReservedName(funcStart->str()))
|
||||
return 0;
|
||||
function.tokenDef = funcStart;
|
||||
|
||||
function.isInline(false);
|
||||
|
@ -3588,3 +3595,28 @@ Function * SymbolDatabase::findFunctionInScope(const Token *func, const Scope *n
|
|||
|
||||
return const_cast<Function *>(function);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
bool SymbolDatabase::isReservedName(const std::string& iName) const
|
||||
{
|
||||
static const std::set<std::string> c_keywords = make_container<std::set<std::string>>() <<
|
||||
"auto" << "break" << "case" << "char" << "const" << "continue" << "default" << "do" <<
|
||||
"double" << "else" << "enum" << "extern" << "float" << "for" << "goto" << "if" << "inline" <<
|
||||
"int" << "long" << "register" << "restrict" << "return" << "short" << "signed" << "sizeof" <<
|
||||
"static" << "struct" << "switch" << "typedef" << "union" << "unsigned" << "void" << "volatile" <<
|
||||
"while";
|
||||
static const std::set<std::string> cpp_keywords = make_container<std::set<std::string>>() <<
|
||||
"alignas" << "alignof" << "and" << "and_eq" << "asm" << "auto" << "bitand" << "bitor" << "bool" <<
|
||||
"break" << "case" << "catch" << "char" << "char16_t" << "char32_t" << "class" << "compl" <<
|
||||
"concept" << "const" << "constexpr" << "const_cast" << "continue" << "decltype" << "default" <<
|
||||
"delete" << "do" << "double" << "dynamic_cast" << "else" << "enum" << "explicit" << "export" <<
|
||||
"extern" << "false" << "float" << "for" << "friend" << "goto" << "if" << "inline" << "int" << "long" <<
|
||||
"mutable" << "namespace" << "new" << "noexcept" << "not" << "not_eq" << "nullptr" << "operator" <<
|
||||
"or" << "or_eq" << "private" << "protected" << "public" << "register" << "reinterpret_cast" <<
|
||||
"requires" << "return" << "short" << "signed" << "sizeof" << "static" << "static_assert" <<
|
||||
"static_cast" << "struct" << "switch" << "template" << "this" << "thread_local" << "throw" <<
|
||||
"true" << "try" << "typedef" << "typeid" << "typename" << "union" << "unsigned" << "using" <<
|
||||
"virtual" << "void" << "volatile" << "wchar_t" << "while" << "xor" << "xor_eq";
|
||||
return (c_keywords.find(iName) != c_keywords.cend()) || (isCPP() && (cpp_keywords.find(iName) != cpp_keywords.cend()));
|
||||
}
|
||||
|
|
|
@ -1005,6 +1005,9 @@ private:
|
|||
const Scope *findNamespace(const Token * tok, const Scope * scope) const;
|
||||
Function *findFunctionInScope(const Token *func, const Scope *ns);
|
||||
|
||||
/** Whether iName is a keyword as defined in http://en.cppreference.com/w/c/keyword and http://en.cppreference.com/w/cpp/keyword*/
|
||||
bool isReservedName(const std::string& iName) const;
|
||||
|
||||
|
||||
const Tokenizer *_tokenizer;
|
||||
const Settings *_settings;
|
||||
|
|
|
@ -78,6 +78,8 @@ private:
|
|||
TEST_CASE(garbageCode37); // #5166
|
||||
TEST_CASE(garbageCode38); // #6666
|
||||
TEST_CASE(garbageCode39); // #6686
|
||||
TEST_CASE(garbageCode40); // #6620
|
||||
TEST_CASE(garbageCode41); // #6685
|
||||
|
||||
TEST_CASE(garbageValueFlow);
|
||||
TEST_CASE(garbageSymbolDatabase);
|
||||
|
@ -455,6 +457,14 @@ private:
|
|||
checkCode("({ (); strcat(strcat(() ()) ()) })");
|
||||
}
|
||||
|
||||
void garbageCode40() { // #6620
|
||||
ASSERT_THROW(checkCode("{ ( ) () { virtual } ; { } E } A { : { } ( ) } * const ( ) const { }"), InternalError);
|
||||
}
|
||||
|
||||
void garbageCode41() { // #6685
|
||||
ASSERT_THROW(checkCode(" { } { return } *malloc(__SIZE_TYPE__ size); *memcpy(void n); static * const () { memcpy (*slot, 3); } { (); } { }"), InternalError);
|
||||
}
|
||||
|
||||
void garbageValueFlow() {
|
||||
// #6089
|
||||
const char* code = "{} int foo(struct, x1, struct x2, x3, int, x5, x6, x7)\n"
|
||||
|
|
|
@ -805,7 +805,7 @@ private:
|
|||
ASSERT_EQUALS("\n\n##file 0\n1: else { if ( ab ) { cd } else { ef } } gh\n", elseif(code));
|
||||
|
||||
// syntax error: assert there is no segmentation fault
|
||||
ASSERT_EQUALS("\n\n##file 0\n1: else if ( x ) { }\n", elseif("else if (x) { }"));
|
||||
ASSERT_THROW(elseif("else if (x) { }"), InternalError);
|
||||
|
||||
{
|
||||
const char src[] = "void f(int g,int f) {\n"
|
||||
|
|
|
@ -1919,8 +1919,7 @@ private:
|
|||
}
|
||||
|
||||
void symboldatabase36() { // ticket #4892
|
||||
check("void struct ( ) { if ( 1 ) } int main ( ) { }");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
ASSERT_THROW(check("void struct ( ) { if ( 1 ) } int main ( ) { }"), InternalError);
|
||||
}
|
||||
|
||||
void symboldatabase37() {
|
||||
|
|
|
@ -1270,7 +1270,7 @@ private:
|
|||
|
||||
void ifAddBraces15() {
|
||||
// ticket #2616 - unknown macro before if
|
||||
ASSERT_EQUALS("{ A if ( x ) { y ( ) ; } }", tokenizeAndStringify("{A if(x)y();}", false));
|
||||
ASSERT_THROW(tokenizeAndStringify("{A if(x)y();}", false), InternalError);
|
||||
}
|
||||
|
||||
void ifAddBraces16() { // ticket # 2739 (segmentation fault)
|
||||
|
@ -6145,7 +6145,7 @@ private:
|
|||
"operator ( ) ; "
|
||||
"}";
|
||||
|
||||
ASSERT_EQUALS(result, tokenizeAndStringify(code,false));
|
||||
ASSERT_EQUALS(result, tokenizeAndStringify(code, /*simplify=*/false, /*expand=*/true, /*platform=*/Settings::Unspecified, "test.c"));
|
||||
}
|
||||
|
||||
void simplifyOperatorName2() {
|
||||
|
|
Loading…
Reference in New Issue