Skip to content

Commit bd34a33

Browse files
Fix #12340 FP knownConditionTrueFalse with typeid (danmar#5877)
1 parent c307d03 commit bd34a33

File tree

4 files changed

+41
-20
lines changed

4 files changed

+41
-20
lines changed

lib/astutils.cpp

+18-16
Original file line numberDiff line numberDiff line change
@@ -1497,6 +1497,20 @@ bool isUsedAsBool(const Token* const tok, const Settings* settings)
14971497
return false;
14981498
}
14991499

1500+
bool compareTokenFlags(const Token* tok1, const Token* tok2, bool macro) {
1501+
if (macro && (tok1->isExpandedMacro() || tok2->isExpandedMacro() || tok1->isTemplateArg() || tok2->isTemplateArg()))
1502+
return false;
1503+
if (tok1->isComplex() != tok2->isComplex())
1504+
return false;
1505+
if (tok1->isLong() != tok2->isLong())
1506+
return false;
1507+
if (tok1->isUnsigned() != tok2->isUnsigned())
1508+
return false;
1509+
if (tok1->isSigned() != tok2->isSigned())
1510+
return false;
1511+
return true;
1512+
};
1513+
15001514
static bool astIsBoolLike(const Token* tok)
15011515
{
15021516
return astIsBool(tok) || isUsedAsBool(tok);
@@ -1613,20 +1627,8 @@ bool isSameExpression(bool cpp, bool macro, const Token *tok1, const Token *tok2
16131627
}
16141628
return false;
16151629
}
1616-
auto flagsDiffer = [](const Token* tok1, const Token* tok2, bool macro) {
1617-
if (macro && (tok1->isExpandedMacro() || tok2->isExpandedMacro() || tok1->isTemplateArg() || tok2->isTemplateArg()))
1618-
return true;
1619-
if (tok1->isComplex() != tok2->isComplex())
1620-
return true;
1621-
if (tok1->isLong() != tok2->isLong())
1622-
return true;
1623-
if (tok1->isUnsigned() != tok2->isUnsigned())
1624-
return true;
1625-
if (tok1->isSigned() != tok2->isSigned())
1626-
return true;
1627-
return false;
1628-
};
1629-
if (flagsDiffer(tok1, tok2, macro))
1630+
1631+
if (!compareTokenFlags(tok1, tok2, macro))
16301632
return false;
16311633

16321634
if (pure && tok1->isName() && tok1->next()->str() == "(" && tok1->str() != "sizeof" && !(tok1->variable() && tok1 == tok1->variable()->nameToken())) {
@@ -1671,7 +1673,7 @@ bool isSameExpression(bool cpp, bool macro, const Token *tok1, const Token *tok2
16711673
const Token *end1 = t1->link();
16721674
const Token *end2 = t2->link();
16731675
while (t1 && t2 && t1 != end1 && t2 != end2) {
1674-
if (t1->str() != t2->str() || flagsDiffer(t1, t2, macro))
1676+
if (t1->str() != t2->str() || !compareTokenFlags(t1, t2, macro))
16751677
return false;
16761678
t1 = t1->next();
16771679
t2 = t2->next();
@@ -1692,7 +1694,7 @@ bool isSameExpression(bool cpp, bool macro, const Token *tok1, const Token *tok2
16921694
const Token *t2 = tok2->next();
16931695
while (t1 && t2 &&
16941696
t1->str() == t2->str() &&
1695-
!flagsDiffer(t1, t2, macro) &&
1697+
compareTokenFlags(t1, t2, macro) &&
16961698
(t1->isName() || t1->str() == "*")) {
16971699
t1 = t1->next();
16981700
t2 = t2->next();

lib/astutils.h

+5
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,11 @@ const Token* isInLoopCondition(const Token* tok);
274274
*/
275275
CPPCHECKLIB bool isUsedAsBool(const Token* const tok, const Settings* settings = nullptr);
276276

277+
/**
278+
* Are the tokens' flags equal?
279+
*/
280+
bool compareTokenFlags(const Token* tok1, const Token* tok2, bool macro);
281+
277282
/**
278283
* Are two conditions opposite
279284
* @param isNot do you want to know if cond1 is !cond2 or if cond1 and cond2 are non-overlapping. true: cond1==!cond2 false: cond1==true => cond2==false

lib/symboldatabase.cpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -1724,7 +1724,7 @@ void SymbolDatabase::createSymbolDatabaseExprIds()
17241724

17251725
// Assign IDs
17261726
ExprIdMap exprIdMap;
1727-
std::map<std::string, nonneg int> baseIds;
1727+
std::map<std::string, std::pair<nonneg int, const Token*>> baseIds;
17281728
for (auto* tok = const_cast<Token*>(scope->bodyStart); tok != scope->bodyEnd; tok = tok->next()) {
17291729
if (tok->varId() > 0) {
17301730
tok->exprId(tok->varId());
@@ -1743,10 +1743,10 @@ void SymbolDatabase::createSymbolDatabaseExprIds()
17431743
++id;
17441744
} else {
17451745
const auto it = baseIds.find(tok->str());
1746-
if (it != baseIds.end()) {
1747-
tok->exprId(it->second);
1746+
if (it != baseIds.end() && compareTokenFlags(tok, it->second.second, /*macro*/ true)) {
1747+
tok->exprId(it->second.first);
17481748
} else {
1749-
baseIds[tok->str()] = id;
1749+
baseIds[tok->str()] = { id, tok };
17501750
tok->exprId(id);
17511751
++id;
17521752
}

test/testvarid.cpp

+14
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,7 @@ class TestVarID : public TestFixture {
243243
TEST_CASE(exprid6);
244244
TEST_CASE(exprid7);
245245
TEST_CASE(exprid8);
246+
TEST_CASE(exprid9);
246247

247248
TEST_CASE(structuredBindings);
248249
}
@@ -3994,6 +3995,19 @@ class TestVarID : public TestFixture {
39943995
ASSERT_EQUALS(expected4, tokenizeExpr(code4));
39953996
}
39963997

3998+
void exprid9()
3999+
{
4000+
const char code[] = "void f(const std::type_info& type) {\n" // #12340
4001+
" if (type == typeid(unsigned int)) {}\n"
4002+
" else if (type == typeid(int)) {}\n"
4003+
"}\n";
4004+
const char expected[] = "1: void f ( const std :: type_info & type ) {\n"
4005+
"2: if ( type@1 ==@UNIQUE typeid (@UNIQUE unsigned int@UNIQUE ) ) { }\n"
4006+
"3: else { if ( type@1 ==@UNIQUE typeid (@UNIQUE int@UNIQUE ) ) { } }\n"
4007+
"4: }\n";
4008+
ASSERT_EQUALS(expected, tokenizeExpr(code));
4009+
}
4010+
39974011
void structuredBindings() {
39984012
const char code[] = "int foo() { auto [x,y] = xy(); return x+y; }";
39994013
ASSERT_EQUALS("1: int foo ( ) { auto [ x@1 , y@2 ] = xy ( ) ; return x@1 + y@2 ; }\n",

0 commit comments

Comments
 (0)