diff --git a/lib/checknullpointer.cpp b/lib/checknullpointer.cpp index 5da68347f..bd96f61b6 100644 --- a/lib/checknullpointer.cpp +++ b/lib/checknullpointer.cpp @@ -761,7 +761,7 @@ void CheckNullPointer::nullPointerByDeRefAndChec() // - logical operators const Token* tok = i->classDef; if ((i->type == Scope::eIf || i->type == Scope::eElseIf || i->type == Scope::eWhile) && - tok && Token::Match(tok, "else| %var% ( !| %var% )|%oror%|&&") && !tok->next()->isExpandedMacro()) { + tok && Token::Match(tok, "else| %var% ( !| %var% )|%oror%|&&") && !tok->tokAt(tok->str()=="else"?1:0)->isExpandedMacro()) { if (tok->str() == "else") tok = tok->next(); diff --git a/lib/tokenlist.cpp b/lib/tokenlist.cpp index 80650adcd..08bdcf7a3 100644 --- a/lib/tokenlist.cpp +++ b/lib/tokenlist.cpp @@ -199,10 +199,13 @@ bool TokenList::createTokens(std::istream &code, const std::string& file0) if (ch == Preprocessor::macroChar) { while (code.peek() == Preprocessor::macroChar) code.get(); - ch = ' '; + if (!CurrentToken.empty()) { + addtoken(CurrentToken.c_str(), lineno, FileIndex, true); + _back->isExpandedMacro(expandedMacro); + } + CurrentToken.clear(); expandedMacro = true; - } else if (ch == '\n') { - expandedMacro = false; + continue; } // char/string.. @@ -317,8 +320,10 @@ bool TokenList::createTokens(std::istream &code, const std::string& file0) } addtoken(CurrentToken.c_str(), lineno, FileIndex, true); - if (!CurrentToken.empty()) + if (!CurrentToken.empty()) { _back->isExpandedMacro(expandedMacro); + expandedMacro = false; + } CurrentToken.clear(); @@ -339,6 +344,7 @@ bool TokenList::createTokens(std::istream &code, const std::string& file0) addtoken(CurrentToken.c_str(), lineno, FileIndex); _back->isExpandedMacro(expandedMacro); CurrentToken.clear(); + expandedMacro = false; continue; } diff --git a/test/testnullpointer.cpp b/test/testnullpointer.cpp index 9a5124beb..67483f823 100644 --- a/test/testnullpointer.cpp +++ b/test/testnullpointer.cpp @@ -498,7 +498,7 @@ private: ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:3]: (warning, inconclusive) Possible null pointer dereference: fred - otherwise it is redundant to check it against null.\n", errout.str()); } - // false positives when there are macros + // #3425 - false positives when there are macros check("void f(struct FRED *fred) {\n" " fred->x = 0;\n" " $if(!fred){}\n" @@ -822,7 +822,7 @@ private: "}"); ASSERT_EQUALS("", errout.str()); - // false positives when there are macros + // #3425 - false positives when there are macros check("void f(int *p) {\n" " *p = 0;\n" " $if(!p){}\n" diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index e108923b7..f3819c677 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -773,7 +773,11 @@ private: } void tokenize22() { // tokenize special marker $ from preprocessor - ASSERT_EQUALS("$a $b", tokenizeAndStringify("a$b")); + ASSERT_EQUALS("a $b", tokenizeAndStringify("a$b")); + ASSERT_EQUALS("a $b\nc", tokenizeAndStringify("a $b\nc")); + ASSERT_EQUALS("a = $0 ;", tokenizeAndStringify("a = $0;")); + ASSERT_EQUALS("a $++ ;", tokenizeAndStringify("a$++;")); + ASSERT_EQUALS("$if ( ! p )", tokenizeAndStringify("$if(!p)")); } // #4195 - segfault for "enum { int f ( ) { return = } r = f ( ) ; }"