[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/cppcheck-opensource/cppcheck/main/test/testunusedfunctions.cpp [Back]  [Original]

/*
 * Cppcheck - A tool for static C/C++ code analysis
 * Copyright (C) 2007-2026 Cppcheck team.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see .
 */

#include "checkunusedfunctions.h"
#include "errortypes.h"
#include "fixture.h"
#include "helpers.h"
#include "platform.h"
#include "settings.h"

#include 
#include 

class TestUnusedFunctions : public TestFixture {
public:
    TestUnusedFunctions() : TestFixture("TestUnusedFunctions") {}

private:
    const Settings settings = settingsBuilder().severity(Severity::style).build();

    void run() override {
        mNewTemplate = true;
        TEST_CASE(incondition);
        TEST_CASE(return1);
        TEST_CASE(return2);
        TEST_CASE(return3);
        TEST_CASE(callback1);
        TEST_CASE(callback2);
        TEST_CASE(else1);
        TEST_CASE(functionpointer);
        TEST_CASE(template1);
        TEST_CASE(template2);
        TEST_CASE(template3);
        TEST_CASE(template4); // #9805
        TEST_CASE(template5);
        TEST_CASE(template6); // #10475 crash
        TEST_CASE(template7); // #9766 crash
        TEST_CASE(template8);
        TEST_CASE(template9);
        TEST_CASE(template10);
        TEST_CASE(throwIsNotAFunction);
        TEST_CASE(unusedError);
        TEST_CASE(unusedMain);
        TEST_CASE(initializationIsNotAFunction);
        TEST_CASE(operator1);   // #3195
        TEST_CASE(operator2);   // #7974
        TEST_CASE(returnRef);
        TEST_CASE(attribute); // #3471 - FP __attribute__(constructor)
        TEST_CASE(initializer_list);
        TEST_CASE(member_function_ternary);
        TEST_CASE(boost);
        TEST_CASE(enumValues);
        TEST_CASE(recursive);

        TEST_CASE(multipleFiles);   // same function name in multiple files

        TEST_CASE(lineNumber); // Ticket 3059

        TEST_CASE(ignore_declaration); // ignore declaration

        TEST_CASE(operatorOverload);

        TEST_CASE(entrypointsWin);
        TEST_CASE(entrypointsWinU);
        TEST_CASE(entrypointsUnix);

        TEST_CASE(virtualFunc);
        TEST_CASE(parensInit);
        TEST_CASE(typeInCast);
        TEST_CASE(attributeCleanup);
        TEST_CASE(attributeUnused);
        TEST_CASE(attributeMaybeUnused);
        TEST_CASE(staticFunction);
        TEST_CASE(unnamedArg);
    }

    struct CheckOptions
    {
        Platform::Type platform = Platform::Type::Native;
        bool cpp = true;
    };

#define check(...) check_(__FILE__, __LINE__, __VA_ARGS__)
    template
    void check_(const char* file, int line, const char (&code)[size], const CheckOptions& options = make_default_obj()) {
        // TODO: avoid copy
        const Settings settings1 = (options.platform == Platform::Type::Native) ? settings : settingsBuilder(settings).platform(options.platform).build();

        check_(file, line, code, settings1, options.cpp);
    }

    template
    void check_(const char* file, int line, const char (&code)[size], const Settings& settings1, bool cpp = true) {
        SimpleTokenizer tokenizer(settings1, *this, cpp);
        ASSERT_LOC(tokenizer.tokenize(code), file, line);

        // Check for unused functions..
        CheckUnusedFunctions checkUnusedFunctions;
        checkUnusedFunctions.parseTokens(tokenizer, settings1.library);
        (checkUnusedFunctions.check)(settings1.library, *this); // TODO: check result
    }

    // TODO: get rid of this
    void check_(const char* file, int line, const std::string& code ) {
        // Tokenize..
        SimpleTokenizer tokenizer(settings, *this);
        ASSERT_LOC(tokenizer.tokenize(code), file, line);

        // Check for unused functions..
        CheckUnusedFunctions checkUnusedFunctions;
        checkUnusedFunctions.parseTokens(tokenizer, settings.library);
        (checkUnusedFunctions.check)(settings.library, *this); // TODO: check result
    }

    void incondition() {
        check("int f1()\n"
              "{\n"
              "    if (f1())\n"
              "    { }\n"
              "}");
        ASSERT_EQUALS("[test.cpp:1:5]: (style) The function 'f1' is never used. [unusedFunction]\n", errout_str());
    }

    void return1() {
        check("int f1()\n"
              "{\n"
              "    return f1();\n"
              "}");
        ASSERT_EQUALS("[test.cpp:1:5]: (style) The function 'f1' is never used. [unusedFunction]\n", errout_str());
    }

    void return2() {
        check("char * foo()\n"
              "{\n"
              "    return foo();\n"
              "}");
        ASSERT_EQUALS("[test.cpp:1:8]: (style) The function 'foo' is never used. [unusedFunction]\n", errout_str());
    }

    void return3() {
        check("typedef void (*VoidFunc)();\n" // #9602
              "void sayHello() {\n"
              "  printf(\"Hello World\\n\");\n"
              "}\n"
              "VoidFunc getEventHandler() {\n"
              "  return sayHello;\n"
              "}\n"
              "void indirectHello() {\n"
              "  VoidFunc handler = getEventHandler();\n"
              "  handler();\n"
              "}\n"
              "int main() {\n"
              "  indirectHello();\n"
              "}");
        ASSERT_EQUALS("", errout_str());
    }

    void callback1() {
        check("void f1()\n"
              "{\n"
              "    void (*f)() = cond ? f1 : NULL;\n"
              "}");
        ASSERT_EQUALS("[test.cpp:1:6]: (style) The function 'f1' is never used. [unusedFunction]\n", errout_str());
    }

    void callback2() { // #8677
        check("class C {\n"
              "public:\n"
              "    void callback();\n"
              "    void start();\n"
              "};\n"
              "\n"
              "void C::callback() {}\n" // 

Web Proxy Viewer  |  New URL  |  Original Page