Сбой CppCheck с определенным синтаксисом шаблона - PullRequest
0 голосов
/ 09 октября 2019

в нашем проекте (VS c ++ 17) у нас есть шаблон, вызывающий сбой CppCheck (версия 1.89, но также и некоторые более ранние версии) без Windows.

Сбой при вызове из командной строки или через графический интерфейс. К сожалению, инструмент выходит таким образом, что я не могу понять, почему он выходит из строя. Через графический интерфейс я попытался принудительно установить версию c ++ на 14, 17 и 20, но безрезультатно.

После отслеживания файла, вызвавшего сбой, я определил следующий синтаксис в заголовке "виновный":

// Header file

template <
    class obj_type,
    template<class> class allocator = SmartPointerAllocator,
    template<class, class> class data_container = std::list>

class EXPORT_OBJECT GenericConfigurationHandler 
{
protected:
    typedef typename allocator<obj_type>::ClientData ClientData;
    typedef data_container<ClientData, std::allocator<ClientData>> TargetConfigurations;
private:
    mutable TargetConfigurations m_target_configurations;

protected:
    TargetConfigurations& get_target_configurations() const { return m_target_configurations; }

public:
    /**
    *   \brief constructor
    */
    GenericConfigurationHandler() = default;

    /**
    *   \brief destructor
    */
    virtual ~GenericConfigurationHandler() {
        std::for_each(m_target_configurations.begin(), m_target_configurations.end(),
            [](ClientData& data) {
            allocator<obj_type>::destroy(data);
        });
    }

    /**
    *   \brief regist a new configuration
    *   \param target_config new target configuration
    */
    template <class src_obj>
    void regist_configuration(const src_obj& target_config) {
        m_target_configurations.push_back(allocator<obj_type>::create(target_config));
    }

    /**
    *   \brief generates target configuration values
    */
    virtual TargetConfigurations build_configurators() const {
        return m_target_configurations;
    }
};

Сам SmartPointerAllocator:

// Header file
template<class T>
struct SmartPointerAllocator {
    //variable type
    typedef typename std::remove_pointer<T>::type var_type;
    //conatiner type
    typedef std::shared_ptr<var_type> ClientData;

    //creator
    template<class obj_type>
    static ClientData create(const obj_type& src_obj) {
        typedef typename std::remove_pointer<obj_type>::type src_obj_type;
        return ClientData(new src_obj_type(src_obj));
    }

    //deallocator
    static void destroy(ClientData& src_obj) {
    }

    static void commit(const ClientData& src_obj) {
        src_obj->commit_configuration();
    }
};

Кроме того, я замечаю, что сбой возникает при загрузке файлов .cpp и чтении / разборе файлов .h. Не во время анализа!

Если я прокомментирую определение шаблона и оставлю «не компилируемый код», как это , анализ пройдет :

// Header file

//template <
//  class obj_type,
//  template<class> class allocator = SmartPointerAllocator,
//  template<class, class> class data_container = std::list>

class EXPORT_OBJECT GenericConfigurationHandler 
{
protected:
    typedef typename allocator<obj_type>::ClientData ClientData;
    typedef data_container<ClientData, std::allocator<ClientData>> TargetConfigurations;
private:
    mutable TargetConfigurations m_target_configurations;

protected:
    TargetConfigurations& get_target_configurations() const { return m_target_configurations; }

public:
    /**
    *   \brief constructor
    */
    GenericConfigurationHandler() = default;

    ...
};

Разница между first и третий код только прокомментированные строки шаблона в начале .

Я пытался избежать конкретного заголовочного файла, но инструмент не позволяет (только файлы cpp)

Есть предложения, как это преодолеть?

1 Ответ

0 голосов
/ 09 октября 2019

Вы можете определить MACRO для cppcheck (например, включить защиту файла заголовка).

Или что-то более конкретное:

#if !defined(CPP_CHECK)
template <
  class obj_type,
  template<class> class allocator = SmartPointerAllocator,
  template<class, class> class data_container = std::list>
#endif
class EXPORT_OBJECT GenericConfigurationHandler
{
    // ...
};

, а затем

cppcheck -DCPP_CHECK file.cpp

...