CppCheck 使用特定的模板语法崩溃
CppCheck crashing with specific template syntax
在我们的项目 (VS c++17) 中,我们有一个模板导致 CppCheck(版本 1.89 但也有一些更早的版本)崩溃 Windows。
如果从命令行或通过 GUI 调用它会崩溃。不幸的是,该工具以一种我无法清楚了解它崩溃原因的方式退出。通过 GUI,我尝试将 c++ 版本强制为 14、17 和 20,但没有效果。
在跟进导致崩溃的文件后,我在 header 中发现以下语法是 "the guilty" 一个:
// 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 文件和reading/parcing .h 文件时。不是在分析过程中!
如果我注释模板定义并像这样留下 "not compilable code" 分析通过:
// 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;
...
};
第一个和第三个代码之间的区别只是注释模板行开头。
我试图转义特定的 header 文件,但该工具不允许(仅 cpp 文件)
有什么克服这个问题的建议吗?
你可以定义MACRO给cppcheck(比如包含头文件的guard)
或更具体的内容:
#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
在我们的项目 (VS c++17) 中,我们有一个模板导致 CppCheck(版本 1.89 但也有一些更早的版本)崩溃 Windows。
如果从命令行或通过 GUI 调用它会崩溃。不幸的是,该工具以一种我无法清楚了解它崩溃原因的方式退出。通过 GUI,我尝试将 c++ 版本强制为 14、17 和 20,但没有效果。
在跟进导致崩溃的文件后,我在 header 中发现以下语法是 "the guilty" 一个:
// 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 文件和reading/parcing .h 文件时。不是在分析过程中!
如果我注释模板定义并像这样留下 "not compilable code" 分析通过:
// 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;
...
};
第一个和第三个代码之间的区别只是注释模板行开头。
我试图转义特定的 header 文件,但该工具不允许(仅 cpp 文件)
有什么克服这个问题的建议吗?
你可以定义MACRO给cppcheck(比如包含头文件的guard)
或更具体的内容:
#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