Skip to content

Commit 6192d0d

Browse files
authored
Add unit tests for expr ids (#5722)
1 parent ae27b61 commit 6192d0d

1 file changed

Lines changed: 267 additions & 3 deletions

File tree

test/testsymboldatabase.cpp

Lines changed: 267 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,14 @@
1616
* along with this program. If not, see <http://www.gnu.org/licenses/>.
1717
*/
1818

19+
#include "errortypes.h"
20+
#include "fixture.h"
21+
#include "helpers.h"
1922
#include "library.h"
2023
#include "platform.h"
2124
#include "settings.h"
25+
#include "sourcelocation.h"
2226
#include "symboldatabase.h"
23-
#include "errortypes.h"
24-
#include "fixture.h"
25-
#include "helpers.h"
2627
#include "token.h"
2728
#include "tokenize.h"
2829
#include "tokenlist.h"
@@ -82,6 +83,60 @@ class TestSymbolDatabase : public TestFixture {
8283
return tokenizer.tokenize(istr, filename) ? tokenizer.getSymbolDatabase() : nullptr;
8384
}
8485

86+
static const Token* findToken(Tokenizer& tokenizer, const std::string& expr, unsigned int exprline)
87+
{
88+
for (const Token* tok = tokenizer.tokens(); tok; tok = tok->next()) {
89+
if (Token::simpleMatch(tok, expr.c_str(), expr.size()) && tok->linenr() == exprline) {
90+
return tok;
91+
}
92+
}
93+
return nullptr;
94+
}
95+
96+
static std::string asExprIdString(const Token* tok)
97+
{
98+
return tok->expressionString() + "@" + std::to_string(tok->exprId());
99+
}
100+
101+
std::string testExprIdEqual(const char code[],
102+
const std::string& expr1,
103+
unsigned int exprline1,
104+
const std::string& expr2,
105+
unsigned int exprline2,
106+
SourceLocation loc = SourceLocation::current())
107+
{
108+
Tokenizer tokenizer(&settings1, this);
109+
std::istringstream istr(code);
110+
ASSERT_LOC(tokenizer.tokenize(istr, "test.cpp"), loc.file_name(), loc.line());
111+
112+
const Token* tok1 = findToken(tokenizer, expr1, exprline1);
113+
const Token* tok2 = findToken(tokenizer, expr2, exprline2);
114+
115+
if (!tok1)
116+
return "'" + expr1 + "'" + " not found";
117+
if (!tok2)
118+
return "'" + expr2 + "'" + " not found";
119+
if (tok1->exprId() == 0)
120+
return asExprIdString(tok1) + " has not exprId";
121+
if (tok2->exprId() == 0)
122+
return asExprIdString(tok2) + " has not exprId";
123+
124+
if (tok1->exprId() != tok2->exprId())
125+
return asExprIdString(tok1) + " != " + asExprIdString(tok2);
126+
127+
return "";
128+
}
129+
bool testExprIdNotEqual(const char code[],
130+
const std::string& expr1,
131+
unsigned int exprline1,
132+
const std::string& expr2,
133+
unsigned int exprline2,
134+
SourceLocation loc = SourceLocation::current())
135+
{
136+
std::string result = testExprIdEqual(code, expr1, exprline1, expr2, exprline2, loc);
137+
return !result.empty();
138+
}
139+
85140
static const Scope *findFunctionScopeByToken(const SymbolDatabase * db, const Token *tok) {
86141
std::list<Scope>::const_iterator scope;
87142

@@ -530,6 +585,7 @@ class TestSymbolDatabase : public TestFixture {
530585
TEST_CASE(unionWithConstructor);
531586

532587
TEST_CASE(incomplete_type); // #9255 (infinite recursion)
588+
TEST_CASE(exprIds);
533589
}
534590

535591
void array() {
@@ -10000,6 +10056,214 @@ class TestSymbolDatabase : public TestFixture {
1000010056

1000110057
ASSERT_EQUALS("", errout.str());
1000210058
}
10059+
10060+
void exprIds()
10061+
{
10062+
const char* code;
10063+
10064+
code = "int f(int a) {\n"
10065+
" return a +\n"
10066+
" a;\n"
10067+
"}\n";
10068+
ASSERT_EQUALS("", testExprIdEqual(code, "a", 2U, "a", 3U));
10069+
10070+
code = "int f(int a, int b) {\n"
10071+
" return a +\n"
10072+
" b;\n"
10073+
"}\n";
10074+
ASSERT_EQUALS(true, testExprIdNotEqual(code, "a", 2U, "b", 3U));
10075+
10076+
code = "int f(int a) {\n"
10077+
" int x = a++;\n"
10078+
" int y = a++;\n"
10079+
" return x + a;\n"
10080+
"}\n";
10081+
ASSERT_EQUALS(true, testExprIdNotEqual(code, "++", 2U, "++", 3U));
10082+
10083+
code = "int f(int a) {\n"
10084+
" int x = a;\n"
10085+
" return x + a;\n"
10086+
"}\n";
10087+
ASSERT_EQUALS(true, testExprIdNotEqual(code, "x", 3U, "a", 3U));
10088+
10089+
code = "int f(int a) {\n"
10090+
" int& x = a;\n"
10091+
" return x + a;\n"
10092+
"}\n";
10093+
TODO_ASSERT_EQUALS("", "x@2 != a@1", testExprIdEqual(code, "x", 3U, "a", 3U));
10094+
10095+
code = "int f(int a) {\n"
10096+
" int& x = a;\n"
10097+
" return (x + 1) +\n"
10098+
" (a + 1);\n"
10099+
"}\n";
10100+
ASSERT_EQUALS("", testExprIdEqual(code, "+", 3U, "+", 4U));
10101+
10102+
code = "int& g(int& x) { return x; }\n"
10103+
"int f(int a) {\n"
10104+
" return (g(a) + 1) +\n"
10105+
" (a + 1);\n"
10106+
"}\n";
10107+
ASSERT_EQUALS("", testExprIdEqual(code, "+", 3U, "+", 4U));
10108+
10109+
code = "int f(int a, int b) {\n"
10110+
" int x = (b-a)-a;\n"
10111+
" int y = (b-a)-a;\n"
10112+
" return x + y;\n"
10113+
"}\n";
10114+
ASSERT_EQUALS("", testExprIdEqual(code, "- a ;", 2U, "- a ;", 3U));
10115+
ASSERT_EQUALS("", testExprIdEqual(code, "- a )", 2U, "- a )", 3U));
10116+
ASSERT_EQUALS(true, testExprIdNotEqual(code, "- a )", 2U, "- a ;", 3U));
10117+
10118+
code = "int f(int a, int b) {\n"
10119+
" int x = a-(b-a);\n"
10120+
" int y = a-(b-a);\n"
10121+
" return x + y;\n"
10122+
"}\n";
10123+
ASSERT_EQUALS("", testExprIdEqual(code, "- ( b", 2U, "- ( b", 3U));
10124+
ASSERT_EQUALS("", testExprIdEqual(code, "- a )", 2U, "- a )", 3U));
10125+
ASSERT_EQUALS(true, testExprIdNotEqual(code, "- a )", 2U, "- ( b", 3U));
10126+
10127+
code = "void f(int a, int b) {\n"
10128+
" int x = (b+a)+a;\n"
10129+
" int y = a+(b+a);\n"
10130+
" return x + y;\n"
10131+
"}\n";
10132+
ASSERT_EQUALS("", testExprIdEqual(code, "+ a ;", 2U, "+ ( b", 3U));
10133+
ASSERT_EQUALS("", testExprIdEqual(code, "+ a ) +", 2U, "+ a ) ;", 3U));
10134+
ASSERT_EQUALS(true, testExprIdNotEqual(code, "+ a ;", 2U, "+ a )", 3U));
10135+
10136+
code = "void f(int a, int b) {\n"
10137+
" int x = (b+a)+a;\n"
10138+
" int y = a+(a+b);\n"
10139+
" return x + y;\n"
10140+
"}\n";
10141+
ASSERT_EQUALS("", testExprIdEqual(code, "+ a ;", 2U, "+ ( a", 3U));
10142+
ASSERT_EQUALS("", testExprIdEqual(code, "+ a ) +", 2U, "+ b ) ;", 3U));
10143+
ASSERT_EQUALS(true, testExprIdNotEqual(code, "+ a ;", 2U, "+ b", 3U));
10144+
10145+
code = "struct A { int x; };\n"
10146+
"void f(A a, int b) {\n"
10147+
" int x = (b-a.x)-a.x;\n"
10148+
" int y = (b-a.x)-a.x;\n"
10149+
" return x + y;\n"
10150+
"}\n";
10151+
ASSERT_EQUALS("", testExprIdEqual(code, "- a . x ;", 3U, "- a . x ;", 4U));
10152+
ASSERT_EQUALS("", testExprIdEqual(code, "- a . x )", 3U, "- a . x )", 4U));
10153+
10154+
code = "struct A { int x; };\n"
10155+
"void f(A a, int b) {\n"
10156+
" int x = a.x-(b-a.x);\n"
10157+
" int y = a.x-(b-a.x);\n"
10158+
" return x + y;\n"
10159+
"}\n";
10160+
ASSERT_EQUALS("", testExprIdEqual(code, "- ( b", 3U, "- ( b", 4U));
10161+
ASSERT_EQUALS("", testExprIdEqual(code, "- a . x )", 3U, "- a . x )", 4U));
10162+
10163+
code = "struct A { int x; };\n"
10164+
"void f(A a) {\n"
10165+
" int x = a.x;\n"
10166+
" int y = a.x;\n"
10167+
" return x + y;\n"
10168+
"}\n";
10169+
ASSERT_EQUALS("", testExprIdEqual(code, ". x", 3U, ". x", 4U));
10170+
10171+
code = "struct A { int x; };\n"
10172+
"void f(A a, A b) {\n"
10173+
" int x = a.x;\n"
10174+
" int y = b.x;\n"
10175+
" return x + y;\n"
10176+
"}\n";
10177+
ASSERT_EQUALS(true, testExprIdNotEqual(code, ". x", 3U, ". x", 4U));
10178+
10179+
code = "struct A { int y; };\n"
10180+
"struct B { A x; }\n"
10181+
"void f(B a) {\n"
10182+
" int x = a.x.y;\n"
10183+
" int y = a.x.y;\n"
10184+
" return x + y;\n"
10185+
"}\n";
10186+
ASSERT_EQUALS("", testExprIdEqual(code, ". x . y", 4U, ". x . y", 5U));
10187+
ASSERT_EQUALS("", testExprIdEqual(code, ". y", 4U, ". y", 5U));
10188+
10189+
code = "struct A { int y; };\n"
10190+
"struct B { A x; }\n"
10191+
"void f(B a, B b) {\n"
10192+
" int x = a.x.y;\n"
10193+
" int y = b.x.y;\n"
10194+
" return x + y;\n"
10195+
"}\n";
10196+
ASSERT_EQUALS(true, testExprIdNotEqual(code, ". x . y", 4U, ". x . y", 5U));
10197+
ASSERT_EQUALS(true, testExprIdNotEqual(code, ". y", 4U, ". y", 5U));
10198+
10199+
code = "struct A { int g(); };\n"
10200+
"struct B { A x; }\n"
10201+
"void f(B a) {\n"
10202+
" int x = a.x.g();\n"
10203+
" int y = a.x.g();\n"
10204+
" return x + y;\n"
10205+
"}\n";
10206+
ASSERT_EQUALS("", testExprIdEqual(code, ". x . g ( )", 4U, ". x . g ( )", 5U));
10207+
ASSERT_EQUALS("", testExprIdEqual(code, ". g ( )", 4U, ". g ( )", 5U));
10208+
10209+
code = "struct A { int g(int, int); };\n"
10210+
"struct B { A x; }\n"
10211+
"void f(B a, int b, int c) {\n"
10212+
" int x = a.x.g(b, c);\n"
10213+
" int y = a.x.g(b, c);\n"
10214+
" return x + y;\n"
10215+
"}\n";
10216+
ASSERT_EQUALS("", testExprIdEqual(code, ". x . g ( b , c )", 4U, ". x . g ( b , c )", 5U));
10217+
ASSERT_EQUALS("", testExprIdEqual(code, ". g ( b , c )", 4U, ". g ( b , c )", 5U));
10218+
10219+
code = "int g();\n"
10220+
"void f() {\n"
10221+
" int x = g();\n"
10222+
" int y = g();\n"
10223+
" return x + y;\n"
10224+
"}\n";
10225+
ASSERT_EQUALS("", testExprIdEqual(code, "(", 3U, "(", 4U));
10226+
10227+
code = "struct A { int g(); };\n"
10228+
"void f() {\n"
10229+
" int x = A::g();\n"
10230+
" int y = A::g();\n"
10231+
" return x + y;\n"
10232+
"}\n";
10233+
ASSERT_EQUALS("", testExprIdEqual(code, "(", 3U, "(", 4U));
10234+
10235+
code = "int g();\n"
10236+
"void f(int a, int b) {\n"
10237+
" int x = g(a, b);\n"
10238+
" int y = g(a, b);\n"
10239+
" return x + y;\n"
10240+
"}\n";
10241+
ASSERT_EQUALS("", testExprIdEqual(code, "(", 3U, "(", 4U));
10242+
10243+
code = "struct A { int g(); };\n"
10244+
"void f() {\n"
10245+
" int x = A::g(a, b);\n"
10246+
" int y = A::g(a, b);\n"
10247+
" return x + y;\n"
10248+
"}\n";
10249+
ASSERT_EQUALS("", testExprIdEqual(code, "(", 3U, "(", 4U));
10250+
10251+
code = "int g();\n"
10252+
"void f(int a, int b) {\n"
10253+
" int x = g(a, b);\n"
10254+
" int y = g(b, a);\n"
10255+
" return x + y;\n"
10256+
"}\n";
10257+
ASSERT_EQUALS(true, testExprIdNotEqual(code, "(", 3U, "(", 4U));
10258+
10259+
code = "struct A { int g(); };\n"
10260+
"void f() {\n"
10261+
" int x = A::g(a, b);\n"
10262+
" int y = A::g(b, a);\n"
10263+
" return x + y;\n"
10264+
"}\n";
10265+
ASSERT_EQUALS(true, testExprIdNotEqual(code, "(", 3U, "(", 4U));
10266+
}
1000310267
};
1000410268

1000510269
REGISTER_TEST(TestSymbolDatabase)

0 commit comments

Comments
 (0)