Merge pull request #596 from simartin/ticket_6620-6685
Ticket #6620, #6685: Reserved keywords cannot be function names.
This commit is contained in:
commit
7c23f4e611
|
@ -745,6 +745,8 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
|
||||||
// save function prototype in database
|
// save function prototype in database
|
||||||
if (newFunc) {
|
if (newFunc) {
|
||||||
Function* func = addGlobalFunctionDecl(scope, tok, argStart, funcStart);
|
Function* func = addGlobalFunctionDecl(scope, tok, argStart, funcStart);
|
||||||
|
if (!func)
|
||||||
|
break;
|
||||||
|
|
||||||
if (Token::Match(argStart->link(), ") const| noexcept")) {
|
if (Token::Match(argStart->link(), ") const| noexcept")) {
|
||||||
int arg = 2;
|
int arg = 2;
|
||||||
|
@ -1658,6 +1660,9 @@ Function* SymbolDatabase::addGlobalFunction(Scope*& scope, const Token*& tok, co
|
||||||
if (!function)
|
if (!function)
|
||||||
function = addGlobalFunctionDecl(scope, tok, argStart, funcStart);
|
function = addGlobalFunctionDecl(scope, tok, argStart, funcStart);
|
||||||
|
|
||||||
|
if (!function)
|
||||||
|
return 0;
|
||||||
|
|
||||||
function->arg = argStart;
|
function->arg = argStart;
|
||||||
function->token = funcStart;
|
function->token = funcStart;
|
||||||
function->hasBody(true);
|
function->hasBody(true);
|
||||||
|
@ -1683,6 +1688,8 @@ Function* SymbolDatabase::addGlobalFunctionDecl(Scope*& scope, const Token *tok,
|
||||||
function.access = Public;
|
function.access = Public;
|
||||||
|
|
||||||
// save the function name location
|
// save the function name location
|
||||||
|
if (funcStart && isReservedName(funcStart->str()))
|
||||||
|
return 0;
|
||||||
function.tokenDef = funcStart;
|
function.tokenDef = funcStart;
|
||||||
|
|
||||||
function.isInline(false);
|
function.isInline(false);
|
||||||
|
@ -3591,3 +3598,28 @@ Function * SymbolDatabase::findFunctionInScope(const Token *func, const Scope *n
|
||||||
|
|
||||||
return const_cast<Function *>(function);
|
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()));
|
||||||
|
}
|
||||||
|
|
|
@ -1006,6 +1006,9 @@ private:
|
||||||
const Scope *findNamespace(const Token * tok, const Scope * scope) const;
|
const Scope *findNamespace(const Token * tok, const Scope * scope) const;
|
||||||
Function *findFunctionInScope(const Token *func, const Scope *ns);
|
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 Tokenizer *_tokenizer;
|
||||||
const Settings *_settings;
|
const Settings *_settings;
|
||||||
|
|
|
@ -78,6 +78,8 @@ private:
|
||||||
TEST_CASE(garbageCode37); // #5166
|
TEST_CASE(garbageCode37); // #5166
|
||||||
TEST_CASE(garbageCode38); // #6666
|
TEST_CASE(garbageCode38); // #6666
|
||||||
TEST_CASE(garbageCode39); // #6686
|
TEST_CASE(garbageCode39); // #6686
|
||||||
|
TEST_CASE(garbageCode40); // #6620
|
||||||
|
TEST_CASE(garbageCode41); // #6685
|
||||||
|
|
||||||
TEST_CASE(garbageValueFlow);
|
TEST_CASE(garbageValueFlow);
|
||||||
TEST_CASE(garbageSymbolDatabase);
|
TEST_CASE(garbageSymbolDatabase);
|
||||||
|
@ -455,6 +457,14 @@ private:
|
||||||
checkCode("({ (); strcat(strcat(() ()) ()) })");
|
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() {
|
void garbageValueFlow() {
|
||||||
// #6089
|
// #6089
|
||||||
const char* code = "{} int foo(struct, x1, struct x2, x3, int, x5, x6, x7)\n"
|
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));
|
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
|
// 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"
|
const char src[] = "void f(int g,int f) {\n"
|
||||||
|
|
|
@ -1920,8 +1920,7 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
void symboldatabase36() { // ticket #4892
|
void symboldatabase36() { // ticket #4892
|
||||||
check("void struct ( ) { if ( 1 ) } int main ( ) { }");
|
ASSERT_THROW(check("void struct ( ) { if ( 1 ) } int main ( ) { }"), InternalError);
|
||||||
ASSERT_EQUALS("", errout.str());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void symboldatabase37() {
|
void symboldatabase37() {
|
||||||
|
|
|
@ -1270,7 +1270,7 @@ private:
|
||||||
|
|
||||||
void ifAddBraces15() {
|
void ifAddBraces15() {
|
||||||
// ticket #2616 - unknown macro before if
|
// 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)
|
void ifAddBraces16() { // ticket # 2739 (segmentation fault)
|
||||||
|
@ -6145,7 +6145,7 @@ private:
|
||||||
"operator ( ) ; "
|
"operator ( ) ; "
|
||||||
"}";
|
"}";
|
||||||
|
|
||||||
ASSERT_EQUALS(result, tokenizeAndStringify(code,false));
|
ASSERT_EQUALS(result, tokenizeAndStringify(code, /*simplify=*/false, /*expand=*/true, /*platform=*/Settings::Unspecified, "test.c"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void simplifyOperatorName2() {
|
void simplifyOperatorName2() {
|
||||||
|
|
Loading…
Reference in New Issue