From 41c94b656a6164dee2d90be23646ec7346d7f233 Mon Sep 17 00:00:00 2001 From: Paul Fultz II Date: Wed, 21 Jul 2021 00:36:13 -0500 Subject: [PATCH] Fix FP const pointer with class variable and add more tests (#3345) --- lib/checkother.cpp | 2 ++ test/testother.cpp | 70 ++++++++++++++++++++++++++++++++++++++++++++++ test/testsuite.h | 1 + 3 files changed, 73 insertions(+) diff --git a/lib/checkother.cpp b/lib/checkother.cpp index d81af7b0d..b70266635 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -1462,6 +1462,8 @@ void CheckOther::checkConstPointer() for (const Token *tok = mTokenizer->tokens(); tok; tok = tok->next()) { if (!tok->variable()) continue; + if (!tok->variable()->isLocal() && !tok->variable()->isArgument()) + continue; if (tok == tok->variable()->nameToken()) continue; if (!tok->valueType()) diff --git a/test/testother.cpp b/test/testother.cpp index a9fe65c54..b3dd0c317 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -2674,6 +2674,76 @@ private: check("void foo(int *p) { return *p > 1; }"); ASSERT_EQUALS("[test.cpp:1]: (style) Parameter 'p' can be declared with const\n", errout.str()); + + check("void foo(const int* c) { if (c == 0) {}; }"); + ASSERT_EQUALS("", errout.str()); + + check("struct a { void b(); };\n" + "struct c {\n" + " a* d;\n" + " a& g() { return *d; }\n" + "};\n"); + ASSERT_EQUALS("", errout.str()); + + check("struct a { void b(); };\n" + "struct c { a* d; };\n" + "void e(c);\n"); + ASSERT_EQUALS("", errout.str()); + + check("struct V {\n" + " V& get(typename std::vector::size_type i, std::vector* arr) {\n" + " return arr->at(i);\n" + " }\n" + "};\n"); + ASSERT_EQUALS("", errout.str()); + + check("struct A {};\n" + "struct B : A {};\n" + "B* f(A* x) {\n" + " return static_cast(x);\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); + + check("int f(std::vector* x) {\n" + " int& i = (*x)[0];\n" + " i++;\n" + " return i;\n" + "}"); + ASSERT_EQUALS("", errout.str()); + + check("struct A { int a; };\n" + "A f(std::vector* x) {\n" + " x->front().a = 1;\n" + " return x->front();\n" + "}"); + ASSERT_EQUALS("", errout.str()); + + check("void f(std::vector* v) {\n" + " for(auto&& x:*v)\n" + " x = 1;\n" + "}"); + ASSERT_EQUALS("", errout.str()); + + check("struct A {\n" + " int* x;\n" + " A(int* y) : x(y)\n" + " {}\n" + "};"); + ASSERT_EQUALS("", errout.str()); + + check("void f(bool b, int* x, int* y) {\n" + " int* z = x;\n" + " int* w = b ? y : z;\n" + " *w = 1;\n" + "}"); + ASSERT_EQUALS("", errout.str()); + + check("void f(bool b, int* x, int* y) {\n" + " int& z = *x;\n" + " int& w = b ? *y : z;\n" + " w = 1;\n" + "}"); + ASSERT_EQUALS("", errout.str()); } void switchRedundantAssignmentTest() { diff --git a/test/testsuite.h b/test/testsuite.h index 767d5842d..b0e47b9d7 100644 --- a/test/testsuite.h +++ b/test/testsuite.h @@ -121,6 +121,7 @@ extern std::ostringstream output; #define TEST_CASE( NAME ) do { if ( prepareTest(#NAME) ) { setVerbose(false); NAME(); } } while(false) #define ASSERT( CONDITION ) if (!assert_(__FILE__, __LINE__, (CONDITION))) return +#define CHECK_EQUALS( EXPECTED , ACTUAL ) assertEquals(__FILE__, __LINE__, (EXPECTED), (ACTUAL)) #define ASSERT_EQUALS( EXPECTED , ACTUAL ) if (!assertEquals(__FILE__, __LINE__, (EXPECTED), (ACTUAL))) return #define ASSERT_EQUALS_WITHOUT_LINENUMBERS( EXPECTED , ACTUAL ) assertEqualsWithoutLineNumbers(__FILE__, __LINE__, EXPECTED, ACTUAL) #define ASSERT_EQUALS_DOUBLE( EXPECTED , ACTUAL, TOLERANCE ) assertEqualsDouble(__FILE__, __LINE__, EXPECTED, ACTUAL, TOLERANCE)