diff --git a/lib/astutils.cpp b/lib/astutils.cpp index c3d70d0cfc0..268b9535b1e 100644 --- a/lib/astutils.cpp +++ b/lib/astutils.cpp @@ -3033,7 +3033,7 @@ bool isLikelyStreamRead(bool cpp, const Token *op) const Token *parent = op; while (parent->astParent() && parent->astParent()->str() == op->str()) parent = parent->astParent(); - if (parent->astParent() && !Token::Match(parent->astParent(), "%oror%|&&|(|,|.|!|;")) + if (parent->astParent() && !Token::Match(parent->astParent(), "%oror%|&&|(|,|.|!|;|return")) return false; if (op->str() == "&" && parent->astParent()) return false; diff --git a/lib/checkstl.cpp b/lib/checkstl.cpp index ceec3cd9b00..ede7460bc1b 100644 --- a/lib/checkstl.cpp +++ b/lib/checkstl.cpp @@ -1992,7 +1992,7 @@ void CheckStl::string_c_str() } } } - } else if (printPerformance && Token::Match(tok, "%var% (|{ %var% . c_str|data ( )") && + } else if (printPerformance && Token::Match(tok, "%var% (|{ %var% . c_str|data ( ) !!,") && tok->variable() && (tok->variable()->isStlStringType() || tok->variable()->isStlStringViewType()) && tok->tokAt(2)->variable() && tok->tokAt(2)->variable()->isStlStringType()) { string_c_strConstructor(tok, tok->variable()->getTypeName()); diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 21efa72c1b3..9b5c4f07850 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -8058,7 +8058,7 @@ void Tokenizer::reportUnknownMacros() const // Report unknown macros before } "{ .. if (x) MACRO }" for (const Token *tok = tokens(); tok; tok = tok->next()) { - if (Token::Match(tok, ")|; %name% }")) { + if (Token::Match(tok, ")|; %name% } !!)")) { const Token* prev = tok->linkAt(2); while (Token::simpleMatch(prev, "{")) prev = prev->previous(); diff --git a/test/testother.cpp b/test/testother.cpp index 33fe01276e1..1c0fb8b9fdd 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -3270,6 +3270,12 @@ class TestOther : public TestFixture { " const int* p = s.g();\n" "}\n"); ASSERT_EQUALS("", errout.str()); + + check("struct S { int x; };\n" // #11818 + "std::istream& f(std::istream& is, S& s) {\n" + " return is >> s.x;\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); } void constParameterCallback() { diff --git a/test/teststl.cpp b/test/teststl.cpp index 77dc8db6bb8..0765d2271dc 100644 --- a/test/teststl.cpp +++ b/test/teststl.cpp @@ -4256,6 +4256,11 @@ class TestStl : public TestFixture { ASSERT_EQUALS("[test.cpp:2]: (performance) Assigning the result of c_str() to a std::string_view is slow and redundant.\n" "[test.cpp:6]: (performance) Constructing a std::string_view from the result of c_str() is slow and redundant.\n", errout.str()); + + check("void f(const std::string& s) {\n" // #11819 + " std::string_view sv(s.data(), 13);\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); } void uselessCalls() { diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index 3688748c349..0ff011e8637 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -6876,6 +6876,10 @@ class TestTokenizer : public TestFixture { ASSERT_THROW(tokenizeAndStringify("void foo() { if(x) SYSTEM_ERROR }"), InternalError); ASSERT_THROW(tokenizeAndStringify("void foo() { dostuff(); SYSTEM_ERROR }"), InternalError); + + ASSERT_NO_THROW(tokenizeAndStringify("void f(void* q) {\n" + " g(&(S) { .p = (int*)q });\n" + "}\n", /*expand*/ true, cppcheck::Platform::Type::Native, "test.c")); } void findGarbageCode() { // Test Tokenizer::findGarbageCode()