📜 ⬆️ ⬇️

PVS-Studio finally got to Boost

Boost and PVS-Studio

We have long wanted to check out the Boost library. We did not have confidence that the results of the test would be enough for an article. However, the desire did not disappear. Two times we tried to do this, but we retreated without understanding how to replace the compiler call with the PVS-Studio.exe call. Now we are armed with new tools, and the third attempt was successful. So, is it possible to find errors in Boost?


Boost


Boost is a collection of free libraries that extend the functionality of C ++. The project was created after the adoption of the C ++ standard, when many were unhappy that some libraries were not included in the standard. The project is a kind of “testing ground” for various language extensions, and some libraries are candidates for inclusion in the following C ++ standards. References:
')


Boost is a “heavy” code in which complex templates are actively used. In a sense, this library is a test for compilers. It often happens that a compiler is able to compile only a part of projects from the modern Boost library.

However, we had problems not with parsing the code. In extreme cases, the analyzer can afford to quietly miss the very confusing design. It turned out to be difficult for us to integrate into the assembly itself.

I will remind the existing options for checking projects with PVS-Studio.

If there is an ordinary project for Visual Studio or Embarcadero C ++ Builder


Everything is simple here. Project analysis can be performed directly from the development environment. Another option is to start PVS-Studio from the command line and get a file with the results of the checkout on exit. This mode is useful in continuous integration systems (for example, Cruise Control, Draco.NET, or Team Foundation Build). This mode is described in more detail in the documentation. About interaction with continuous integration systems can be found here .

If there is no project (or the project is essentially a disguised makefile)


In this case, you need to create an assembly mode, when instead of the compiler (or with it) the code analyzer is launched. The output also produces a report file. The necessary magic spells are also described in the documentation. In this case, the magician must be very careful, study the manual in detail and not forget a single character.

This is the approach we should have used to test Boost. It’s a pity we were insufficiently magicians or just lazy. It was not possible to figure out the build system in order to transfer all the necessary parameters to the console version of the analyzer.

We came to the aid of a new third option verification projects


My colleague has already mentioned this mode in a recent post “ From the Cellar of the Secret PVS-Studio Developer's Lab ”. No need to fully integrate into the assembly system. It is enough just to get preprocessed * .i files . It is much easier. That is what we did.

Then, using the prototype of the new tool (PVS-Studio Standalone), we performed an analysis of all * .i files and received a long-awaited report. In the same program, you can conveniently work with the list of errors and make corrections to the code.

I hope we will include this tool in the distribution kit through several versions. Perhaps this will happen in PVS-Studio 5.10.

A few words about the regime, which is not, but which we dream


We are slowly getting closer to tracking the actions of the compiler. This mode will also apply to the PVS-Studio Standalone tool. All starts of the compiler will be tracked and keys of its start will be collected. Thus, it will be sufficient to perform the following steps. Order - "watch." Build a project using any build system. Say - "done." And the analyzer will know how to check the project now. Of course, if the project structure or parameters change, this process will have to be repeated. All right, dreaming, and now back to the Boost checkout.

Sense of hopelessness


I was ready to not write an article about Boost. This sad assumption had the following prerequisites.

A large number of compilers and tools


Boost is built by a large number of compilers. Some partially, some completely. I did not study this issue. But, as I understand it, Boost is pretty well built using Visual C ++, Intel C ++, Sun Studio, Compaq C ++, GCC, Clang. Each compiler has its own unique diagnostic capabilities. And their total use should provide a very high quality code. One compiler will find error A, second error B, and so on.

Moreover, the Boost library is a kind of testing ground for various tools and static code analyzers. Since Boost actively uses various modern C ++ features, it is always interesting to know if the tool can deal with such code. As a result, Boost is checked and re-checked by various code analyzers.

Looking for errors and typos after so many compilers and other tools is almost hopeless.

A large number of users


The Boost library is used in many projects. At one time, we ourselves used Boost in the PVS-Studio project (then still Viva64). We used mechanisms for working with regular expressions, with configuration files and a couple of other trifles. Then we realized that regular expressions are a dead end, and gradually they disappeared from the code. Dragging Boost only because of the configuration files was doubtful. Moreover, some unpleasant flaws became clear. For example, in the file name can not use '#'. This character is considered to be the beginning of a comment. In our particular case, Boost did not catch on, however, it is certainly a very useful library.

Since the library is widely used, errors should be quickly detected by programmers. Errors can only remain in rarely used code fragments or in exotic subsystems that have few users.

Templates


Boost has many template classes. They are almost impossible to verify if they are not instantiated. For example, Visual C ++ does not parse template classes at all if they are not used. In an unused class, you can write any rubbish and the file is successfully compiled. Enough to observe the number of opening and closing parentheses and quotes (), <>, {}, [], "", ".

Analyzing the template class, you have to compromise between the number of false positives and the omission of errors. Let me explain with a simple example, what is the difficulty.
template <typename T>
bool IsNAN(T x) { return x != x; }

, « » (Not-a-Number). float/double/long double. , .

, ? . . . . . , PVS-Studio . - , - .

. Boost .


, . , . , .

3-4 Boost .

, PVS-Studio 5.06 Boost 1.55 ( ).

Boost


. .

N1.


point3D operator/(const point3D &p1, const point3D &p2)
{
  return point3D( p1.x/p2.x , p1.y/p2.y , p1.z/p1.z );
}

PVS-Studio: V501 There are identical sub-expressions to the left and to the right of the '/' operator: p1.z / p1.z lorenz_point.cpp 61

, 'p1.z' . , 'p2.z'.

N2.


BOOST_UBLAS_INLINE
compressed_matrix_view(const compressed_matrix_view& o) :
  size1_(size1_), size2_(size2_),
  nnz_(nnz_),
  index1_data_(index1_data_),
  index2_data_(index2_data_),
  value_data_(value_data_)
{}

PVS-Studio ( ): V546 Member of a class is initialized by itself: 'size1_(size1_)'. sparse_view.hpp 193

. , . , 'o'. , :
BOOST_UBLAS_INLINE
compressed_matrix_view(const compressed_matrix_view& o) :
  size1_(o.size1_), size2_(o.size2_),
  nnz_(o.nnz_),
  index1_data_(o.index1_data_),
  index2_data_(o.index2_data_),
  value_data_(o.value_data_)
{}


N3.


static std::basic_string<wchar_t> get(char const* source = "")
{
  ....
  std::auto_ptr<wchar_t> result (new wchar_t[len+1]);
  ....
}

PVS-Studio: V554 Incorrect use of auto_ptr. The memory allocated with 'new []' will be cleaned using 'delete'. tree_to_xml.ipp 71

'std::auto_ptr' . 'delete', 'delete []'. , . "delete, new[] C++ ".

: generate_static.hpp 53.

N4. . SOCKET


-, , , SOCKET. . :
SOCKET s = Foo();
if (s < 0) { Error(); }

. SOCKET_ERROR. , «socket < 0» «socket >= 0».

Linux SOCKET . Windows SOCKET . , .

Boost.
typedef SOCKET socket_type;

class socket_holder
{
  ....
  socket_type socket_;
  ....
  socket_type get() const { return socket_; }
  ....
};

template <typename Socket>
boost::system::error_code accept(....)
{
  ....
  // On success, assign new connection to peer socket object.
  if (new_socketnew_socket.get() >= 0)
  {
    if (peer_endpoint)
      peer_endpoint->resize(addr_len);
    if (!peer.assign(impl.protocol_, new_socket.get(), ec))
      new_socket.release();
  }
  return ec;
}

PVS-Studio: V547 Expression 'new_socket.get() >= 0' is always true. Unsigned type value is always >= 0. win_iocp_socket_service.hpp 436

Windows , . «new_socketnew_socket.get() >= 0» .

N5.


void set_duration_style(duration_style style)
{
  duration_style_ == style;
}

PVS-Studio: V607 Ownerless expression 'duration_style_ == style'. base_formatter.hpp 51

. , , : «duration_style_ = style». .

, PVS-Studio . . . , . , . PVS-Studio . . , .

? ( ). , . , . , , : , TDD, .

N6.


template< typename CharT >
basic_settings< CharT > parse_settings(std::basic_istream< CharT >& strm)
{
  ....
  string_type line;
  while (!strm.eof())
  {
     std::getline(strm, line);

     const char_type* p = line.c_str();
     parser.parse_line(p, p + line.size());

     line.clear();
     ++line_number;
  }
  ....
}

PVS-Studio: V663 Infinite loop is possible. The 'cin.eof()' condition is insufficient to break from the loop. Consider adding the 'cin.fail()' function call to the conditional expression. settings_parser.cpp 285

, — . , . , , . . , . 'eof()' 'false'. . 'eof()' 'fail()'. 'fail()' , . .

: V663 Infinite loop is possible. The 'cin.eof()' condition is insufficient to break from the loop. Consider adding the 'cin.fail()' function call to the conditional expression. adjacency_list_io.hpp 195

N7.


template<> 
struct identity_element<boost::gregorian::date_duration>
{
  static boost::gregorian::date_duration value()
  { 
    return
      boost::gregorian::date(boost::gregorian::min_date_time) -
      boost::gregorian::date(boost::gregorian::min_date_time); 
  }
};

PVS-Studio: V501 There are identical sub-expressions 'boost::gregorian::date(boost::gregorian::min_date_time)' to the left and to the right of the '-' operator. gregorian.hpp 57

, 0?


, PVS-Studio . - Boost . !

Source: https://habr.com/ru/post/190888/


All Articles