From 285ef96b5ba7fa25e388e0fad6d9e0acaa38a87d Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Wed, 18 Oct 2023 18:46:47 +0200 Subject: [PATCH] Report unknownMacro in string concatenation (refs #11378) (#5558) --- lib/tokenize.cpp | 3 ++- test/testtokenize.cpp | 5 +++++ test/testuninitvar.cpp | 16 ++++++++-------- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index f967bb060..be6b403b5 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -8277,7 +8277,8 @@ void Tokenizer::reportUnknownMacros() const // String concatenation with unknown macros for (const Token *tok = tokens(); tok; tok = tok->next()) { - if (Token::Match(tok, "%str% %name% (") && Token::Match(tok->linkAt(2), ") %str%")) { + if ((Token::Match(tok, "%str% %name% (") && Token::Match(tok->linkAt(2), ") %str%")) || + (Token::Match(tok, "%str% %name% %str%") && !(startsWith(tok->strAt(1), "PRI") || startsWith(tok->strAt(1), "SCN")))) { // TODO: implement macros in std.cfg if (tok->next()->isKeyword()) continue; unknownMacroError(tok->next()); diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index ad5fc40af..801897163 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -6899,6 +6899,11 @@ private: "void f(float a) {\n" "S s = (S){ .i = (int)a };\n" "}\n", /*expand*/ true, Platform::Type::Native, "test.c")); + + ASSERT_THROW(tokenizeAndStringify("std::string g();\n" + "std::string f() {\n" + " return std::string{ g() + \"abc\" MACRO \"def\" };\n" + "}\n", /*expand*/ true, Platform::Type::Native, "test.cpp"), InternalError); } void findGarbageCode() { // Test Tokenizer::findGarbageCode() diff --git a/test/testuninitvar.cpp b/test/testuninitvar.cpp index 6e4abe8d8..7e7a2cdd6 100644 --- a/test/testuninitvar.cpp +++ b/test/testuninitvar.cpp @@ -3530,10 +3530,10 @@ private: "}"); ASSERT_EQUALS("[test.cpp:5]: (error) Uninitialized variable: a\n", errout.str()); - checkUninitVar("void f() {\n" // Don't crash - " int a;\n" - " dostuff(\"ab\" cd \"ef\", x?a:z);\n" // <- No AST is created for ?: - "}"); + ASSERT_THROW(checkUninitVar("void f() {\n" // Don't crash + " int a;\n" + " dostuff(\"ab\" cd \"ef\", x?a:z);\n" // <- No AST is created for ? + "}"), InternalError); // Unknown => bail out.. checkUninitVar("void f(int x) {\n" @@ -3652,10 +3652,10 @@ private: "}"); ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:5]: (warning) Uninitialized variable: a\n", errout.str()); - valueFlowUninit("void f() {\n" // Don't crash - " int a;\n" - " dostuff(\"ab\" cd \"ef\", x?a:z);\n" // <- No AST is created for ?: - "}"); + ASSERT_THROW(valueFlowUninit("void f() {\n" // Don't crash + " int a;\n" + " dostuff(\"ab\" cd \"ef\", x?a:z);\n" // <- No AST is created for ? + "}"), InternalError); // Unknown => bail out.. valueFlowUninit("void f(int x) {\n"