This commit is contained in:
parent
f6f489ea49
commit
7bfd686f04
|
@ -1539,6 +1539,13 @@ std::string Token::astStringVerbose() const
|
|||
return ret;
|
||||
}
|
||||
|
||||
std::string Token::astStringZ3() const {
|
||||
if (!astOperand1())
|
||||
return str();
|
||||
if (!astOperand2())
|
||||
return "(" + str() + " " + astOperand1()->astStringZ3() + ")";
|
||||
return "(" + str() + " " + astOperand1()->astStringZ3() + " " + astOperand2()->astStringZ3() + ")";
|
||||
}
|
||||
|
||||
void Token::printValueFlow(bool xml, std::ostream &out) const
|
||||
{
|
||||
|
|
|
@ -1282,6 +1282,8 @@ public:
|
|||
|
||||
std::string astStringVerbose() const;
|
||||
|
||||
std::string astStringZ3() const;
|
||||
|
||||
std::string expressionString() const;
|
||||
|
||||
void printAst(bool verbose, bool xml, std::ostream &out) const;
|
||||
|
|
|
@ -1020,6 +1020,17 @@ static void compilePrecedence3(Token *&tok, AST_state& state)
|
|||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
Token* leftToken = tok;
|
||||
while (Token::Match(tok->next(), ":: %name%"))
|
||||
{
|
||||
Token* scopeToken = tok->next(); //The ::
|
||||
scopeToken->astOperand1(leftToken);
|
||||
scopeToken->astOperand2(scopeToken->next());
|
||||
leftToken = scopeToken;
|
||||
tok = scopeToken->next();
|
||||
}
|
||||
|
||||
state.op.push(tok);
|
||||
while (Token::Match(tok, "%name%|*|&|<|::")) {
|
||||
if (tok->link())
|
||||
|
|
|
@ -188,6 +188,14 @@ private:
|
|||
ASSERT_EQUALS(true, isSameExpression("void f() {double y = 1e1; (x + y) < (x + 10.0); } ", "+", "+"));
|
||||
ASSERT_EQUALS(true, isSameExpression("void f() {double y = 1e1; (x + 10.0) < (y + x); } ", "+", "+"));
|
||||
ASSERT_EQUALS(true, isSameExpression("void f() {double y = 1e1; double z = 10.0; (x + y) < (x + z); } ", "+", "+"));
|
||||
ASSERT_EQUALS(true, isSameExpression("A + A", "A", "A"));
|
||||
|
||||
//https://trac.cppcheck.net/ticket/9700
|
||||
ASSERT_EQUALS(true, isSameExpression("A::B + A::B;", "::", "::"));
|
||||
ASSERT_EQUALS(false, isSameExpression("A::B + A::C;", "::", "::"));
|
||||
ASSERT_EQUALS(true, isSameExpression("A::B* get() { if(x) return new A::B(true); else return new A::B(true); }", "new", "new"));
|
||||
ASSERT_EQUALS(false, isSameExpression("A::B* get() { if(x) return new A::B(true); else return new A::C(true); }", "new", "new"));
|
||||
ASSERT_EQUALS(true, true);
|
||||
}
|
||||
|
||||
bool isVariableChanged(const char code[], const char startPattern[], const char endPattern[]) {
|
||||
|
|
|
@ -130,6 +130,7 @@ private:
|
|||
TEST_CASE(duplicateBranch1); // tests extracted by http://www.viva64.com/en/b/0149/ ( Comparison between PVS-Studio and cppcheck ): Errors detected in Quake 3: Arena by PVS-Studio: Fragment 2
|
||||
TEST_CASE(duplicateBranch2); // empty macro
|
||||
TEST_CASE(duplicateBranch3);
|
||||
TEST_CASE(duplicateBranch4);
|
||||
TEST_CASE(duplicateExpression1);
|
||||
TEST_CASE(duplicateExpression2); // ticket #2730
|
||||
TEST_CASE(duplicateExpression3); // ticket #3317
|
||||
|
@ -4101,6 +4102,17 @@ private:
|
|||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
void duplicateBranch4() {
|
||||
check("void* f(bool b) {\n"
|
||||
" if (b) {\n"
|
||||
" return new A::Y(true);\n"
|
||||
" } else {\n"
|
||||
" return new A::Z(true);\n"
|
||||
" }\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
void duplicateExpression1() {
|
||||
check("void foo(int a) {\n"
|
||||
" if (a == a) { }\n"
|
||||
|
|
|
@ -99,8 +99,8 @@ extern std::ostringstream errout;
|
|||
extern std::ostringstream output;
|
||||
|
||||
#define TEST_CASE( NAME ) do { if ( prepareTest(#NAME) ) { setVerbose(false); NAME(); } } while(false)
|
||||
#define ASSERT( CONDITION ) if (!assert_(__FILE__, __LINE__, CONDITION)) return
|
||||
#define ASSERT_EQUALS( EXPECTED , ACTUAL ) if (!assertEquals(__FILE__, __LINE__, EXPECTED, ACTUAL)) return
|
||||
#define ASSERT( CONDITION ) if (!assert_(__FILE__, __LINE__, (CONDITION))) return
|
||||
#define ASSERT_EQUALS( EXPECTED , ACTUAL ) if (!assertEquals(__FILE__, __LINE__, (EXPECTED), (ACTUAL))) return
|
||||
#define ASSERT_EQUALS_WITHOUT_LINENUMBERS( EXPECTED , ACTUAL ) assertEqualsWithoutLineNumbers(__FILE__, __LINE__, EXPECTED, ACTUAL)
|
||||
#define ASSERT_EQUALS_DOUBLE( EXPECTED , ACTUAL, TOLERANCE ) assertEqualsDouble(__FILE__, __LINE__, EXPECTED, ACTUAL, TOLERANCE)
|
||||
#define ASSERT_EQUALS_MSG( EXPECTED , ACTUAL, MSG ) assertEquals(__FILE__, __LINE__, EXPECTED, ACTUAL, MSG)
|
||||
|
|
|
@ -461,6 +461,7 @@ private:
|
|||
TEST_CASE(astcase);
|
||||
TEST_CASE(astrefqualifier);
|
||||
TEST_CASE(astvardecl);
|
||||
TEST_CASE(astnewscoped);
|
||||
|
||||
TEST_CASE(startOfExecutableScope);
|
||||
|
||||
|
@ -7376,7 +7377,7 @@ private:
|
|||
ASSERT_EQUALS("a ? ( b < c ) : d > e", tokenizeAndStringify("a ? b < c : d > e"));
|
||||
}
|
||||
|
||||
std::string testAst(const char code[],bool verbose=false) {
|
||||
std::string testAst(const char code[], bool verbose = false, bool z3 = false) {
|
||||
// tokenize given code..
|
||||
Tokenizer tokenList(&settings0, nullptr);
|
||||
std::istringstream istr(code);
|
||||
|
@ -7408,6 +7409,8 @@ private:
|
|||
}
|
||||
|
||||
// Return stringified AST
|
||||
if (z3)
|
||||
return tokenList.list.front()->astTop()->astStringZ3();
|
||||
if (verbose)
|
||||
return tokenList.list.front()->astTop()->astStringVerbose();
|
||||
|
||||
|
@ -7920,6 +7923,23 @@ private:
|
|||
ASSERT_EQUALS("b(", testAst("class a { void b() & {} };"));
|
||||
}
|
||||
|
||||
//Verify that returning a newly constructed object generates the correct AST even when the class name is scoped
|
||||
//Addresses https://trac.cppcheck.net/ticket/9700
|
||||
void astnewscoped() {
|
||||
ASSERT_EQUALS("(return (new A))", testAst("return new A;", false, true));
|
||||
ASSERT_EQUALS("(return (new (( A)))", testAst("return new A();", false, true));
|
||||
ASSERT_EQUALS("(return (new (( A true)))", testAst("return new A(true);", false, true));
|
||||
ASSERT_EQUALS("(return (new (:: A B)))", testAst("return new A::B;", false, true));
|
||||
ASSERT_EQUALS("(return (new (( (:: A B))))", testAst("return new A::B();", false, true));
|
||||
ASSERT_EQUALS("(return (new (( (:: A B) true)))", testAst("return new A::B(true);", false, true));
|
||||
ASSERT_EQUALS("(return (new (:: (:: A B) C)))", testAst("return new A::B::C;", false, true));
|
||||
ASSERT_EQUALS("(return (new (( (:: (:: A B) C))))", testAst("return new A::B::C();", false, true));
|
||||
ASSERT_EQUALS("(return (new (( (:: (:: A B) C) true)))", testAst("return new A::B::C(true);", false, true));
|
||||
ASSERT_EQUALS("(return (new (:: (:: (:: A B) C) D)))", testAst("return new A::B::C::D;", false, true));
|
||||
ASSERT_EQUALS("(return (new (( (:: (:: (:: A B) C) D))))", testAst("return new A::B::C::D();", false, true));
|
||||
ASSERT_EQUALS("(return (new (( (:: (:: (:: A B) C) D) true)))", testAst("return new A::B::C::D(true);", false, true));
|
||||
}
|
||||
|
||||
void compileLimits() {
|
||||
const char raw_code[] = "#define PTR1 (* (* (* (* (* (* (* (* (* (*\n"
|
||||
"#define PTR2 PTR1 PTR1 PTR1 PTR1 PTR1 PTR1 PTR1 PTR1 PTR1 PTR1\n"
|
||||
|
|
Loading…
Reference in New Issue