From d8b59dd886162e6cb19e5466031fc5c7adfcc8e0 Mon Sep 17 00:00:00 2001 From: chrchr-github Date: Mon, 8 Apr 2024 21:13:30 +0200 Subject: [PATCH] Add test --- lib/checkclass.h | 4 ++-- test/testclass.cpp | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/lib/checkclass.h b/lib/checkclass.h index 4808944f214..bc2a9d5116d 100644 --- a/lib/checkclass.h +++ b/lib/checkclass.h @@ -91,7 +91,7 @@ class CPPCHECKLIB CheckClass : public Check { checkClass.checkCopyCtorAndEqOperator(); checkClass.checkOverride(); checkClass.checkUselessOverride(); - checkClass.checkReturnReference(); + checkClass.checkReturnByReference(); checkClass.checkThisUseAfterFree(); checkClass.checkUnsafeClassRefMember(); } @@ -159,7 +159,7 @@ class CPPCHECKLIB CheckClass : public Check { void checkUselessOverride(); /** @brief Check that large members are returned by reference from getter function */ - void checkReturnReference(); + void checkReturnByReference(); /** @brief When "self pointer" is destroyed, 'this' might become invalid. */ void checkThisUseAfterFree(); diff --git a/test/testclass.cpp b/test/testclass.cpp index 7b628149e63..465caef5d0c 100644 --- a/test/testclass.cpp +++ b/test/testclass.cpp @@ -243,6 +243,8 @@ class TestClass : public TestFixture { TEST_CASE(ctuOneDefinitionRule); TEST_CASE(testGetFileInfo); + + TEST_CASE(returnByReference); } #define checkCopyCtorAndEqOperator(code) checkCopyCtorAndEqOperator_(code, __FILE__, __LINE__) @@ -8959,6 +8961,36 @@ class TestClass : public TestFixture { getFileInfo("struct sometype { sometype(); }; sometype::sometype() = delete;"); // don't crash } +#define checkReturnByReference(...) checkReturnByReference_(__FILE__, __LINE__, __VA_ARGS__) + void checkReturnByReference_(const char* file, int line, const char code[]) { + const Settings settings = settingsBuilder().severity(Severity::performance).library("std.cfg").build(); + + std::vector files(1, "test.cpp"); + Tokenizer tokenizer(settings, this); + PreprocessorHelper::preprocess(code, files, tokenizer); + + ASSERT_LOC(tokenizer.simplifyTokens1(""), file, line); + + // Check.. + CheckClass checkClass(&tokenizer, &settings, this); + (checkClass.checkReturnByReference)(); + } + + void returnByReference() { + checkReturnByReference("struct T { int a[10]; };" // #12546 + "struct S {" + " T t;" + " int i;" + " std::string s;" + " T getT() const { return t; }" + " int getI() const { return i; }" + " std::string getS() const { return s; }" + "};"); + ASSERT_EQUALS("[test.cpp:1]: (style) Function 'getT()' should return member 't' by const reference.\n" + "[test.cpp:1]: (style) Function 'getS()' should return member 's' by const reference.\n", + errout_str()); + } + }; REGISTER_TEST(TestClass)