Skip to content

Commit 6ac804d

Browse files
Fix #12178 extern "C++" scope generates valueflow (#5654)
1 parent 9228b9e commit 6ac804d

3 files changed

Lines changed: 47 additions & 6 deletions

File tree

lib/tokenize.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3592,17 +3592,18 @@ void Tokenizer::simplifyExternC()
35923592

35933593
// Add attributes to all tokens within `extern "C"` inlines and blocks, and remove the `extern "C"` tokens.
35943594
for (Token *tok = list.front(); tok; tok = tok->next()) {
3595-
if (Token::simpleMatch(tok, "extern \"C\"")) {
3595+
if (Token::Match(tok, "extern \"C\"|\"C++\"")) {
35963596
Token *tok2 = tok->next();
3597+
const bool isExtC = tok->next()->str().size() == 3;
35973598
if (tok->strAt(2) == "{") {
35983599
tok2 = tok2->next(); // skip {
35993600
while ((tok2 = tok2->next()) && tok2 != tok->linkAt(2))
3600-
tok2->isExternC(true);
3601+
tok2->isExternC(isExtC);
36013602
tok->linkAt(2)->deleteThis(); // }
36023603
tok->deleteNext(2); // "C" {
36033604
} else {
36043605
while ((tok2 = tok2->next()) && !Token::Match(tok2, "[;{]"))
3605-
tok2->isExternC(true);
3606+
tok2->isExternC(isExtC);
36063607
tok->deleteNext(); // "C"
36073608
}
36083609
tok->deleteThis(); // extern

test/testsimplifytemplate.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4163,7 +4163,8 @@ class TestSimplifyTemplate : public TestFixture {
41634163

41644164
void template163() { // #9685 syntax error
41654165
const char code[] = "extern \"C++\" template < typename T > T * test ( ) { return nullptr ; }";
4166-
ASSERT_EQUALS(code, tok(code));
4166+
const char expected[] = "template < typename T > T * test ( ) { return nullptr ; }";
4167+
ASSERT_EQUALS(expected, tok(code));
41674168
}
41684169

41694170
void template164() { // #9394

test/testtokenize.cpp

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1548,8 +1548,47 @@ class TestTokenizer : public TestFixture {
15481548

15491549

15501550
void simplifyExternC() {
1551-
ASSERT_EQUALS("int foo ( ) ;", tokenizeAndStringify("extern \"C\" int foo();"));
1552-
ASSERT_EQUALS("int foo ( ) ;", tokenizeAndStringify("extern \"C\" { int foo(); }"));
1551+
const char expected[] = "int foo ( ) ;";
1552+
{
1553+
const char code[] = "extern \"C\" int foo();";
1554+
// tokenize..
1555+
Tokenizer tokenizer(&settings0, this);
1556+
std::istringstream istr(code);
1557+
ASSERT(tokenizer.tokenize(istr, "test.cpp"));
1558+
// Expected result..
1559+
ASSERT_EQUALS(expected, tokenizer.tokens()->stringifyList(nullptr, false));
1560+
ASSERT(tokenizer.tokens()->next()->isExternC());
1561+
}
1562+
{
1563+
const char code[] = "extern \"C\" { int foo(); }";
1564+
// tokenize..
1565+
Tokenizer tokenizer(&settings0, this);
1566+
std::istringstream istr(code);
1567+
ASSERT(tokenizer.tokenize(istr, "test.cpp"));
1568+
// Expected result..
1569+
ASSERT_EQUALS(expected, tokenizer.tokens()->stringifyList(nullptr, false));
1570+
ASSERT(tokenizer.tokens()->next()->isExternC());
1571+
}
1572+
{
1573+
const char code[] = "extern \"C++\" int foo();";
1574+
// tokenize..
1575+
Tokenizer tokenizer(&settings0, this);
1576+
std::istringstream istr(code);
1577+
ASSERT(tokenizer.tokenize(istr, "test.cpp"));
1578+
// Expected result..
1579+
ASSERT_EQUALS(expected, tokenizer.tokens()->stringifyList(nullptr, false));
1580+
ASSERT(!tokenizer.tokens()->next()->isExternC());
1581+
}
1582+
{
1583+
const char code[] = "extern \"C++\" { int foo(); }";
1584+
// tokenize..
1585+
Tokenizer tokenizer(&settings0, this);
1586+
std::istringstream istr(code);
1587+
ASSERT(tokenizer.tokenize(istr, "test.cpp"));
1588+
// Expected result..
1589+
ASSERT_EQUALS(expected, tokenizer.tokens()->stringifyList(nullptr, false));
1590+
ASSERT(!tokenizer.tokens()->next()->isExternC());
1591+
}
15531592
}
15541593

15551594
void simplifyFunctionParameters() {

0 commit comments

Comments
 (0)