From 8819e19daed5afe3d1322ba0da3b193be69ad590 Mon Sep 17 00:00:00 2001 From: Rikard Falkeborn Date: Mon, 27 Jan 2020 06:55:01 +0100 Subject: [PATCH] Fix #8489 (Fix FN printf argument with parenthesis) (#2508) --- lib/checkio.cpp | 2 ++ test/testio.cpp | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/lib/checkio.cpp b/lib/checkio.cpp index f7061ee8f..be5be668f 100644 --- a/lib/checkio.cpp +++ b/lib/checkio.cpp @@ -1323,6 +1323,8 @@ CheckIO::ArgumentInfo::ArgumentInfo(const Token * arg, const Settings *settings, // TODO: This is a bailout so that old code is used in simple cases. Remove the old code and always use the AST type. if (!Token::Match(arg, "%str% ,|)") && !(Token::Match(arg,"%var%") && arg->variable() && arg->variable()->isArray())) { const Token *top = arg; + while (top->str() == "(" && !top->isCast()) + top = top->next(); while (top->astParent() && top->astParent()->str() != "," && top->astParent() != arg->previous()) top = top->astParent(); const ValueType *valuetype = top->argumentType(); diff --git a/test/testio.cpp b/test/testio.cpp index 96823fa30..30e01e730 100644 --- a/test/testio.cpp +++ b/test/testio.cpp @@ -73,6 +73,7 @@ private: TEST_CASE(testPrintfTypeAlias1); TEST_CASE(testPrintfAuto); // #8992 + TEST_CASE(testPrintfParenthesis); // #8489 } void check(const char* code, bool inconclusive = false, bool portability = false, Settings::PlatformType platform = Settings::Unspecified) { @@ -4804,6 +4805,23 @@ private: "}\n", false, true); ASSERT_EQUALS("[test.cpp:4]: (portability) %f in format string (no. 1) requires 'double' but the argument type is 'size_t {aka unsigned long}'.\n", errout.str()); } + + void testPrintfParenthesis() { // #8489 + check("void f(int a) {\n" + " printf(\"%f\", (a >> 24) & 0xff);\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:2]: (warning) %f in format string (no. 1) requires 'double' but the argument type is 'signed int'.\n", errout.str()); + + check("void f(int a) {\n" + " printf(\"%f\", 0xff & (a >> 24));\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:2]: (warning) %f in format string (no. 1) requires 'double' but the argument type is 'signed int'.\n", errout.str()); + + check("void f(int a) {\n" + " printf(\"%f\", ((a >> 24) + 1) & 0xff);\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:2]: (warning) %f in format string (no. 1) requires 'double' but the argument type is 'signed int'.\n", errout.str()); + } }; REGISTER_TEST(TestIO)