Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions lib/astutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1607,6 +1607,21 @@ bool isSameExpression(bool macro, const Token *tok1, const Token *tok2, const Se
return true;
if (tok1 == nullptr || tok2 == nullptr)
return false;
// An unknown string-prefix macro leaves the literal outside the AST.
// Compare the literal text as well so identical literals still compare equal.
const bool stringPrefix1 = !tok1->isKeyword() && Token::Match(tok1, "%name% %str%");
const bool stringPrefix2 = !tok2->isKeyword() && Token::Match(tok2, "%name% %str%");
if (stringPrefix1 || stringPrefix2) {
if (!stringPrefix1 || !stringPrefix2)
return false;
for (const Token* str1 = tok1->next(), *str2 = tok2->next();
Token::Match(str1, "%str%") || Token::Match(str2, "%str%");
str1 = str1->next(), str2 = str2->next()) {
if (!Token::Match(str1, "%str%") || !Token::Match(str2, "%str%") ||
str1->str() != str2->str() || !compareTokenFlags(str1, str2, macro))
return false;
}
}
// tokens needs to be from the same TokenList so no need check standard on both of them
if (tok1->isCpp()) {
if (tok1->str() == "." && tok1->astOperand1() && tok1->astOperand1()->str() == "this")
Expand Down
11 changes: 11 additions & 0 deletions test/testastutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -198,11 +198,22 @@ class TestAstUtils : public TestFixture {
ASSERT_EQUALS(!cpp, isSameExpression("void f() {double y = 1e1; (x + 10.0) < (y + x); } \n", "+", "+", cpp));
ASSERT_EQUALS(true, isSameExpression("void f() {double y = 1e1; double z = 10.0; (x + y) < (x + z); } \n", "+", "+", cpp));
ASSERT_EQUALS(true, isSameExpression("A + A\n", "A", "A", cpp));
// An unknown string-prefix macro leaves the literal outside the AST. #5738
ASSERT_EQUALS(false, isSameExpression("x == PREFIX \"/a\" || x == PREFIX \"/b\";\n", "==", "==", cpp));
ASSERT_EQUALS(false, isSameExpression("x == PREFIX \"/a\" || x == PREFIX;\n", "==", "==", cpp));
ASSERT_EQUALS(false, isSameExpression("x == PREFIX || x == PREFIX \"/a\";\n", "==", "==", cpp));
ASSERT_EQUALS(true, isSameExpression("x == PREFIX \"/a\" || x == PREFIX \"/a\";\n", "==", "==", cpp));
ASSERT_EQUALS(true, isSameExpression("x == PREFIX \"/a\" \"/b\" || x == PREFIX \"/a\" \"/b\";\n", "==", "==", cpp));
ASSERT_EQUALS(false, isSameExpression("x == PREFIX \"/a\" \"/b\" || x == PREFIX \"/a\" \"/c\";\n", "==", "==", cpp));
ASSERT_EQUALS(false, isSameExpression("x == FIRST \"/a\" || x == SECOND \"/a\";\n", "==", "==", cpp));
ASSERT_EQUALS(false, isSameExpression("x == PREFIX L\"/a\" || x == PREFIX \"/a\";\n", "==", "==", cpp));

// the remaining test cases are not valid C code
if (!cpp)
return;

ASSERT_EQUALS(true, isSameExpression("void f(int x) { x ? throw \"a\" : throw \"a\"; }\n", "throw", "throw", cpp));

//https://trac.cppcheck.net/ticket/9700
ASSERT_EQUALS(true, isSameExpression("A::B + A::B;\n", "::", "::", cpp));
ASSERT_EQUALS(false, isSameExpression("A::B + A::C;\n", "::", "::", cpp));
Expand Down
12 changes: 12 additions & 0 deletions test/testother.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12163,6 +12163,18 @@ class TestOther : public TestFixture {
" return name.startswith(SRCDIR \"/com/\") || name.startswith(SRCDIR \"/uno/\");\n"
"};\n", dinit(CheckOptions, $.inconclusive = false));
ASSERT_EQUALS("", errout_str());

check("bool isInUnoIncludeFile(StringRef name) {\n"
" return isInMainFile()\n"
" ? (name == SRCDIR \"/cppu/compat.cxx\" || name == SRCDIR \"/sal/compat.cxx\")\n"
" : (name.startswith(SRCDIR \"/com/\") || name.startswith(SRCDIR \"/uno/\"));\n"
"}\n", dinit(CheckOptions, $.inconclusive = false));
ASSERT_EQUALS("", errout_str());

check("bool f(StringRef name) {\n"
" return name == SRCDIR \"/a\" || name == SRCDIR \"/a\";\n"
"}\n", dinit(CheckOptions, $.inconclusive = false));
ASSERT_EQUALS("[test.cpp:2:32]: (style) Same expression on both sides of '||'. [duplicateExpression]\n", errout_str());
}

void raceAfterInterlockedDecrement() {
Expand Down