Fix #12178 extern "C++" scope generates valueflow (#5654)

This commit is contained in:
chrchr-github 2023-11-14 10:02:41 +01:00 committed by GitHub
parent 9228b9e424
commit 6ac804d209
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 47 additions and 6 deletions

View File

@ -3592,17 +3592,18 @@ void Tokenizer::simplifyExternC()
// Add attributes to all tokens within `extern "C"` inlines and blocks, and remove the `extern "C"` tokens.
for (Token *tok = list.front(); tok; tok = tok->next()) {
if (Token::simpleMatch(tok, "extern \"C\"")) {
if (Token::Match(tok, "extern \"C\"|\"C++\"")) {
Token *tok2 = tok->next();
const bool isExtC = tok->next()->str().size() == 3;
if (tok->strAt(2) == "{") {
tok2 = tok2->next(); // skip {
while ((tok2 = tok2->next()) && tok2 != tok->linkAt(2))
tok2->isExternC(true);
tok2->isExternC(isExtC);
tok->linkAt(2)->deleteThis(); // }
tok->deleteNext(2); // "C" {
} else {
while ((tok2 = tok2->next()) && !Token::Match(tok2, "[;{]"))
tok2->isExternC(true);
tok2->isExternC(isExtC);
tok->deleteNext(); // "C"
}
tok->deleteThis(); // extern

View File

@ -4163,7 +4163,8 @@ private:
void template163() { // #9685 syntax error
const char code[] = "extern \"C++\" template < typename T > T * test ( ) { return nullptr ; }";
ASSERT_EQUALS(code, tok(code));
const char expected[] = "template < typename T > T * test ( ) { return nullptr ; }";
ASSERT_EQUALS(expected, tok(code));
}
void template164() { // #9394

View File

@ -1548,8 +1548,47 @@ private:
void simplifyExternC() {
ASSERT_EQUALS("int foo ( ) ;", tokenizeAndStringify("extern \"C\" int foo();"));
ASSERT_EQUALS("int foo ( ) ;", tokenizeAndStringify("extern \"C\" { int foo(); }"));
const char expected[] = "int foo ( ) ;";
{
const char code[] = "extern \"C\" int foo();";
// tokenize..
Tokenizer tokenizer(&settings0, this);
std::istringstream istr(code);
ASSERT(tokenizer.tokenize(istr, "test.cpp"));
// Expected result..
ASSERT_EQUALS(expected, tokenizer.tokens()->stringifyList(nullptr, false));
ASSERT(tokenizer.tokens()->next()->isExternC());
}
{
const char code[] = "extern \"C\" { int foo(); }";
// tokenize..
Tokenizer tokenizer(&settings0, this);
std::istringstream istr(code);
ASSERT(tokenizer.tokenize(istr, "test.cpp"));
// Expected result..
ASSERT_EQUALS(expected, tokenizer.tokens()->stringifyList(nullptr, false));
ASSERT(tokenizer.tokens()->next()->isExternC());
}
{
const char code[] = "extern \"C++\" int foo();";
// tokenize..
Tokenizer tokenizer(&settings0, this);
std::istringstream istr(code);
ASSERT(tokenizer.tokenize(istr, "test.cpp"));
// Expected result..
ASSERT_EQUALS(expected, tokenizer.tokens()->stringifyList(nullptr, false));
ASSERT(!tokenizer.tokens()->next()->isExternC());
}
{
const char code[] = "extern \"C++\" { int foo(); }";
// tokenize..
Tokenizer tokenizer(&settings0, this);
std::istringstream istr(code);
ASSERT(tokenizer.tokenize(istr, "test.cpp"));
// Expected result..
ASSERT_EQUALS(expected, tokenizer.tokens()->stringifyList(nullptr, false));
ASSERT(!tokenizer.tokens()->next()->isExternC());
}
}
void simplifyFunctionParameters() {