From a3d1cac79c91fe5989f8759c28460d692856f858 Mon Sep 17 00:00:00 2001 From: Simon Martin Date: Sat, 8 Mar 2014 20:56:39 +0100 Subject: [PATCH] Ticket #5373: Keep track whether tokens come from a C or C++ file to properly handle %type% in Token::Match with "delete" --- lib/token.cpp | 4 +++- lib/token.h | 4 ++++ lib/tokenize.cpp | 2 ++ test/testtokenize.cpp | 14 ++++++++++++++ tools/matchcompiler.py | 4 ++-- 5 files changed, 25 insertions(+), 3 deletions(-) diff --git a/lib/token.cpp b/lib/token.cpp index 39bd518c7..186bec00a 100644 --- a/lib/token.cpp +++ b/lib/token.cpp @@ -29,6 +29,8 @@ #include #include +bool Token::_isCPP = true; + Token::Token(Token **t) : tokensBack(t), _next(0), @@ -600,7 +602,7 @@ bool Token::Match(const Token *tok, const char pattern[], unsigned int varid) // Type (%type%) { p += 5; - multicompare(p,tok->isName() && tok->varId() == 0 && tok->str() != "delete",ismulticomp); + multicompare(p, tok->isName() && tok->varId() == 0 && (tok->str() != "delete" || !Token::isCPP()), ismulticomp); } break; case 'a': diff --git a/lib/token.h b/lib/token.h index 80b0a6c24..72d787dda 100644 --- a/lib/token.h +++ b/lib/token.h @@ -679,6 +679,8 @@ private: // original name like size_t std::string _originalName; + static bool _isCPP; + public: void astOperand1(Token *tok); void astOperand2(Token *tok); @@ -728,6 +730,8 @@ public: void printAst(bool verbose) const; void printValueFlow() const; + static void isCPP(bool isCPP) { _isCPP = isCPP; } + static bool isCPP() { return _isCPP; } }; /// @} diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 734ebdf61..fce9988a9 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -1589,6 +1589,8 @@ bool Tokenizer::tokenize(std::istream &code, return false; } + Token::isCPP(isCPP()); + if (simplifyTokenList1()) { createSymbolDatabase(); diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index 5b868698b..71a24574e 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -263,6 +263,7 @@ private: TEST_CASE(varid53); // #4172 - Template instantiation: T<&functionName> list[4]; TEST_CASE(varid54); // hang TEST_CASE(varid_cpp_keywords_in_c_code); + TEST_CASE(varid_cpp_keywords_in_c_code2); // #5373: varid=0 for argument called "delete" TEST_CASE(varidFunctionCall1); TEST_CASE(varidFunctionCall2); TEST_CASE(varidFunctionCall3); @@ -3985,6 +3986,19 @@ private: ASSERT_EQUALS(expected, tokenizeDebugListing(code,false,"test.c")); } + void varid_cpp_keywords_in_c_code2() { // #5373 + const char code[] = "int clear_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, " + "unsigned long bits, int wake, int delete, struct extent_state **cached_state, " + "gfp_t mask) {\n" + " struct extent_state *state;\n" + "}" + "int clear_extent_dirty() {\n" + " return clear_extent_bit(tree, start, end, EXTENT_DIRTY | EXTENT_DELALLOC | " + " EXTENT_DO_ACCOUNTING, 0, 0, NULL, mask);\n" + "}"; + tokenizeDebugListing(code, false, "test.c"); + } + void varidFunctionCall1() { const std::string code("void f() {\n" " int x;\n" diff --git a/tools/matchcompiler.py b/tools/matchcompiler.py index 29774b9f3..87ea1f868 100755 --- a/tools/matchcompiler.py +++ b/tools/matchcompiler.py @@ -113,8 +113,8 @@ class MatchCompiler: return '(tok->type()==Token::eString)' elif tok == '%type%': return ( - '(tok->isName() && tok->varId()==0U && tok->str() != ' + - self._insertMatchStr('delete') + '/* delete */)' + '(tok->isName() && tok->varId()==0U && (tok->str() != ' + + self._insertMatchStr('delete') + '/* delete */ || !Token::isCPP()))' ) elif tok == '%var%': return 'tok->isName()'