in our project (VS c++17) we have a template causing CppCheck (version 1.89 but also some earlier versions) to crash no Windows.
It crashes if called from command line or via GUI. Unfortunately the tool exits in a way I cannot get clear idea why it crashes. Via the GUI I tried forcing the c++ version to 14, 17 and 20 but no effect.
After following up on the file causing the crash I identified the following syntax in header is "the guilty" one:
// 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;
}
};
The SmartPointerAllocator itself is:
// 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();
}
};
What I further notice is the crash appears on loading the .cpp files and reading/parcing the .h files. Not during the analysis!
If I comment the template definition and leave "not compilable code" like this the analysis passes:
// 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;
...
};
The difference between first and third code is only the commented template lines at the beginning.
I tried to escape the particular header file but the tool does not allow (only cpp files)
Any suggestions how to overcome this?
You can define MACRO to cppcheck (include guard of the header file for example).
Or something more specific:
#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
{
// ...
};
and then
cppcheck -DCPP_CHECK file.cpp