From 9c38a659a10d136b441a0e355600710f85cabb97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sat, 11 Jan 2020 12:16:48 +0100 Subject: [PATCH] Clang import; Fixed CXXConstructExpr without child --- lib/clangimport.cpp | 49 +++++++++++++++++++++++++--------------- lib/cppcheck.cpp | 10 +++++++- test/testclangimport.cpp | 13 +++++++++-- 3 files changed, 51 insertions(+), 21 deletions(-) diff --git a/lib/clangimport.cpp b/lib/clangimport.cpp index 7d5ecb5d3..681dc205c 100644 --- a/lib/clangimport.cpp +++ b/lib/clangimport.cpp @@ -253,10 +253,15 @@ std::string clangimport::AstNode::getSpelling() const std::string clangimport::AstNode::getType() const { - int typeIndex = mExtTokens.size() - 1; - while (typeIndex >= 0 && mExtTokens[typeIndex][0] != '\'') - typeIndex--; - return typeIndex == -1 ? "" : unquote(mExtTokens[typeIndex]); + int typeIndex = 1; + typeIndex = 1; + while (typeIndex < mExtTokens.size() && mExtTokens[typeIndex][0] != '\'') + typeIndex++; + if (typeIndex >= mExtTokens.size()) + return ""; + if (mExtTokens[typeIndex].find("\':\'") != std::string::npos) + return mExtTokens[typeIndex].substr(1, mExtTokens[typeIndex].find("\':\'") - 1); + return unquote(mExtTokens[typeIndex]); } std::string clangimport::AstNode::getTemplateParameters() const @@ -481,18 +486,6 @@ Token *clangimport::AstNode::createTokens(TokenList *tokenList) } if (nodeType == ContinueStmt) return addtoken(tokenList, "continue"); - if (nodeType == CXXConstructorDecl) { - bool hasBody = false; - for (AstNodePtr child: children) { - if (child->nodeType == CompoundStmt && !child->children.empty()) { - hasBody = true; - break; - } - } - if (hasBody) - createTokensFunctionDecl(tokenList); - return nullptr; - } if (nodeType == CStyleCastExpr) { Token *par1 = addtoken(tokenList, "("); addTypeTokens(tokenList, '\'' + getType() + '\''); @@ -507,8 +500,28 @@ Token *clangimport::AstNode::createTokens(TokenList *tokenList) tokenList->back()->setValueType(new ValueType(ValueType::Sign::UNKNOWN_SIGN, ValueType::Type::BOOL, 0)); return tokenList->back(); } - if (nodeType == CXXConstructExpr) - return children[0]->createTokens(tokenList); + if (nodeType == CXXConstructExpr) { + if (!children.empty()) + return children[0]->createTokens(tokenList); + addTypeTokens(tokenList, '\'' + getType() + '\''); + Token *par1 = addtoken(tokenList, "("); + Token *par2 = addtoken(tokenList, ")"); + par1->link(par2); + par2->link(par1); + return par1; + } + if (nodeType == CXXConstructorDecl) { + bool hasBody = false; + for (AstNodePtr child: children) { + if (child->nodeType == CompoundStmt && !child->children.empty()) { + hasBody = true; + break; + } + } + if (hasBody) + createTokensFunctionDecl(tokenList); + return nullptr; + } if (nodeType == CXXMethodDecl) { createTokensFunctionDecl(tokenList); return nullptr; diff --git a/lib/cppcheck.cpp b/lib/cppcheck.cpp index fd28b4605..17053c0c6 100644 --- a/lib/cppcheck.cpp +++ b/lib/cppcheck.cpp @@ -242,6 +242,8 @@ const char * CppCheck::extraVersion() unsigned int CppCheck::check(const std::string &path) { if (mSettings.clang) { + mErrorLogger.reportOut(std::string("Checking ") + path + "..."); + const std::string clang = Path::isCPP(path) ? "clang++" : "clang"; /* Experimental: import clang ast dump */ @@ -269,6 +271,8 @@ unsigned int CppCheck::check(const std::string &path) } } + //std::cout << "Clang flags: " << flags << std::endl; + for (const std::string &i: mSettings.includePaths) flags += "-I" + i + " "; @@ -286,7 +290,11 @@ unsigned int CppCheck::check(const std::string &path) //ValueFlow::setValues(&tokenizer.list, const_cast(tokenizer.getSymbolDatabase()), this, &mSettings); if (mSettings.debugnormal) tokenizer.printDebugOutput(1); - ExprEngine::runChecks(this, &tokenizer, &mSettings); + +#ifdef USE_Z3 + if (mSettings.verification) + ExprEngine::runChecks(this, &tokenizer, &mSettings); +#endif return 0; } diff --git a/test/testclangimport.cpp b/test/testclangimport.cpp index d4c0eed2d..80d6d5ff6 100644 --- a/test/testclangimport.cpp +++ b/test/testclangimport.cpp @@ -38,7 +38,8 @@ private: TEST_CASE(cstyleCastExpr); TEST_CASE(cxxBoolLiteralExpr); TEST_CASE(cxxConstructorDecl); - TEST_CASE(cxxConstructExpr); + TEST_CASE(cxxConstructExpr1); + TEST_CASE(cxxConstructExpr2); TEST_CASE(cxxMemberCall); TEST_CASE(cxxNullPtrLiteralExpr); TEST_CASE(cxxOperatorCallExpr); @@ -202,7 +203,7 @@ private: ASSERT_EQUALS("void C ( ) { this . x@1 = 0 ; } int x@1", parse(clang)); } - void cxxConstructExpr() { + void cxxConstructExpr1() { const char clang[] = "`-FunctionDecl 0x2dd7940 col:5 f 'Foo (Foo)'\n" " |-ParmVarDecl 0x2dd7880 col:11 used foo 'Foo'\n" " `-CompoundStmt 0x2dd80c0 \n" @@ -213,6 +214,14 @@ private: ASSERT_EQUALS("Foo f ( Foo foo@1 ) { return foo@1 ; }", parse(clang)); } + void cxxConstructExpr2() { + const char clang[] = "`-FunctionDecl 0x3e44180 <1.cpp:2:1, col:30> col:13 f 'std::string ()'\n" + " `-CompoundStmt 0x3e4cb80 \n" + " `-ReturnStmt 0x3e4cb68 \n" + " `-CXXConstructExpr 0x3e4cb38 'std::string':'std::__cxx11::basic_string' '....' list"; + ASSERT_EQUALS("std::string f ( ) { return std::string ( ) ; }", parse(clang)); + } + void cxxMemberCall() { const char clang[] = "`-FunctionDecl 0x320dc80 col:6 bar 'void ()'\n" " `-CompoundStmt 0x323bb08 \n"