
Checking the Qt 5 Framework

Static code analysis tools allow you to eliminate many errors even at the stage of writing the program text. For example, typos can be quickly identified and eliminated. Some programmers are sincerely sure that they do not make typos and silly mistakes. This is not true. Everyone makes such mistakes. This article will serve as a good demo. Typos can be found even in such a quality and tested project as Qt.
Qt
Qt is a cross-platform software development toolkit in the C ++ programming language. Allows you to run software written with its help in most modern operating systems by simply compiling a program for each OS without changing the source code. It includes all the main classes that may be required when developing application software, ranging from GUI elements to classes for working with the network, databases, and XML. Qt is fully object oriented, easily extensible, and supports component programming techniques. [source: Wikipedia]
Links:
- Wikipedia - Qt ;
- Qt Project website ;
- An article about our verification of Qt 4.7.3 in 2011.
I want to draw attention to the fact that PVS-Studio managed to find errors, despite the fact that the Qt project was checked using the Klocwork and Coverity analyzers. I do not know how regularly these analyzers are used. However, Klocwork and Coverity are mentioned in bugtracker and ChangeLog-xxx files. I also found a mention on the Internet that Qt is regularly checked using PC-lint.
Features of Qt project validation
For a change, we tested Qt with the new mechanism introduced in PVS-Studio Standalone. Nobody knows about the mechanism yet, and from time to time we will remind in the articles about its existence. What is this new mysterious and beautiful mechanism?
It is sometimes difficult to verify a project using PVS-Studio if it is built using nmake and the like. It is required to integrate PVS-Studio into the assembly, which is not so simple. At the very least, this clearly makes it difficult to quickly try and evaluate the tool.
Now in PVS-Studio a new operating mode has appeared, which will greatly facilitate the work with such projects. The analyzer can monitor with what parameters the compiler is launched and collects all the information necessary for verification. It is enough to tell the analyzer when to start surveillance and when to stop it.
Compiler tracking can be done both from the application GUI and from the command line. More details on how all this works and how to use the new mode are described in the article:
Evgeny Ryzhkov. PVS-Studio now supports any build system on Windows and any compiler. Easy and out of the box .
This article describes how the Qt project was tested in command-line monitoring start mode.
Be sure to ask to read this article so that there are less misunderstandings. For example, while compilation of a project is being monitored, you cannot do programming in parallel. If you compile files from another project, information about them will be collected, and they will also be checked. As a result, messages related to another project will be included in the report. It will turn out a mess.
Validation Results
In general, I got the following impression about the code:
Qt code is high-quality and practically does not contain errors associated with dangerous features of the C ++ language. But a lot of ordinary typos.
This article will demonstrate well that regardless of professionalism, all developers make typos. The benefit of static code analysis was, is and will be. Suppose the analyzer found 10 typos on a single run. So, if you use it regularly, by now it would have prevented hundreds or thousands of mistakes. This is a huge time saver. It is much more profitable to detect an error immediately after it appears in the code than to find it when debugging the code or thanks to a user complaint.
Plunge into the wonderful world of typos

Typo N1
bool QWindowsUser32DLL::initTouch()
{
QSystemLibrary library(QStringLiteral("user32"));
registerTouchWindow = ....;
unregisterTouchWindow = ....;
getTouchInputInfo = ....;
closeTouchInputHandle = ....;
return registerTouchWindow &&
unregisterTouchWindow &&
getTouchInputInfo &&
getTouchInputInfo;
}
PVS-Studio Warning: V501 There are identical sub-expressions 'getTouchInputInfo' to the left and to the right of the '&&' operator. qwindowscontext.cpp 216
Four variables are assigned values. These four variables should be checked. But because of a typo only 3 is checked. In the last line, instead of 'getTouchInputInfo' should be written 'closeTouchInputHandle'.
Typo N2
QWindowsNativeImage *QWindowsFontEngine::drawGDIGlyph(....)
{
....
int iw = gm.width.toInt();
int ih = gm.height.toInt();
if (iw <= 0 || iw <= 0)
return 0;
....
}
PVS-Studio Warning: V501 There are identical sub-expressions to the left and to the right of the '||' operator: iw <= 0 || iw <= 0 qwindowsfontengine.cpp 1095
There is no height check stored in the variable 'ih'.
Typo N3, N4
This error is related to tests. A good example of how static analysis complements unit tests. More on this topic: " How Static Analysis Supplements TDD ."
inline bool qCompare(QImage const &t1, QImage const &t2, ....)
{
....
if (t1.width() != t2.width() || t2.height() != t2.height()) {
....
}
PVS-Studio warning: V501 There are identical sub-expressions to the left and to the right of the '! =' Operator: t2.height ()! = T2.height () qtest_gui.h 101
The function of comparing two images incorrectly compares them height. Rather, it does not compare at all.
Error propagated using Copy-Paste. Exactly the same comparison can be seen in the same file just below (line 135).
Typo N5
I'm sorry that I ugly formatted the code. The lines were too long.
void QXmlSimpleReader::setFeature(
const QString& name, bool enable)
{
....
} else if ( name == QLatin1String(
"http://trolltech.com/xml/features/report-start-end-entity")
|| name == QLatin1String(
"http://trolltech.com/xml/features/report-start-end-entity"))
{
....
}
PVS-Studio Warning: V501 There are identical sub-expressions to the left and to the right of the '||' operator. qxml.cpp 3249 The
variable 'name' is compared twice to the same string. Above in the code, there is a similar comparison. There the variable is compared with these two with strings:
- http: // trolltech.com / xml / features / report-whitespace-only-CharData
- http: // qt-project.org / xml / features / report-whitespace-only-CharData
- http: // trolltech.com / xml / features / report-start-end-entity
- http: // qt-project.org / xml / features / report-start-end-entity
QString DayTimeDuration::stringValue() const
{
....
if(!m_hours && !m_minutes && !m_seconds && !m_seconds)
....
}
PVS-Studio Warning: V501 There are identical sub-expressions '! M_seconds' to the left and to the right of the '&&' operator. qdaytimeduration.cpp 148
Forgot about milliseconds. Milliseconds are stored in the variable 'm_mseconds'. The check should be like this:
if(!m_hours && !m_minutes && !m_seconds && !m_mseconds)
An identical error with milliseconds is in three more places:
- qdaytimeduration.cpp 170
- qduration.cpp 167
- qduration.cpp 189
QV4::ReturnedValue
QQuickJSContext2DPrototype::method_getImageData(
QV4::CallContext *ctx)
{
....
qreal x = ctx->callData->args[0].toNumber();
qreal y = ctx->callData->args[1].toNumber();
qreal w = ctx->callData->args[2].toNumber();
qreal h = ctx->callData->args[3].toNumber();
if (!qIsFinite(x) || !qIsFinite(y) ||
!qIsFinite(w) || !qIsFinite(w))
....
}
PVS-Studio Warning: V501 There are identical sub-expressions '! QIsFinite (w)' to the left and to the right of the '||' operator. qquickcontext2d.cpp 3305
There is no verification of the variable 'h'. Instead, the variable 'w' is checked twice.
Typo N11
AtomicComparator::ComparisonResult
IntegerComparator::compare(const Item &o1,
const AtomicComparator::Operator,
const Item &o2) const
{
const Numeric *const num1 = o1.as();
const Numeric *const num2 = o1.as();
if(num1->isSigned() || num2->isSigned())
....
}
V656 Variables 'num1', 'num2' are initialized through the call to the same function. It's probably an error or un-optimized code. Consider inspecting the 'o1.as <Numeric> ()' expression. Check lines: 220, 221. qatomiccomparators.cpp 221 The
variables 'num1' and 'num2' are initialized with the same value. Both of these variables are checked below. This is suspicious. After all, it is enough to check the value of only one variable.
Most likely, the variable 'num2' should be initialized with an expression where the argument 'o2' is used:
const Numeric *const num1 = o1.as();
const Numeric *const num2 = o2.as();
Typo N12
void Atlas::uploadBgra(Texture *texture)
{
const QRect &r = texture->atlasSubRect();
QImage image = texture->image();
if (image.format() != QImage::Format_ARGB32_Premultiplied ||
image.format() != QImage::Format_RGB32) {
....
}
V547 Expression is always true. Probably the '&&' operator should be used here. qsgatlastexture.cpp 271 The
condition in this code does not make sense. She is always true. To make it easier to understand what is wrong here, I will give a simplified example:
int a = ...;
if (a != 1 || a != 2)
A variable will always be unequal to something.
I do not know what the correct code should look like. Maybe it should be like this:
if (image.format() == QImage::Format_ARGB32_Premultiplied ||
image.format() == QImage::Format_RGB32) {
Or so:
if (image.format() != QImage::Format_ARGB32_Premultiplied &&
image.format() != QImage::Format_RGB32) {
Typo N13
void QDeclarativeStateGroupPrivate::setCurrentStateInternal(
const QString &state,
bool ignoreTrans)
{
....
QDeclarativeTransition *transition =
(ignoreTrans || ignoreTrans) ?
0 : findTransition(currentState, state);
....
}
PVS-Studio Warning: V501 There are identical sub-expressions to the left and to the right of the '||' operator: ignoreTrans || ignoreTrans qdeclarativestategroup.cpp 442
Something is wrong here. How exactly they wanted to write a check is not clear to me.
Typo N14
QV4::ReturnedValue
QQuickJSContext2DPrototype::method_createPattern(....)
{
....
if (repetition == QStringLiteral("repeat") ||
repetition.isEmpty()) {
pattern->patternRepeatX = true;
pattern->patternRepeatY = true;
} else if (repetition == QStringLiteral("repeat-x")) {
pattern->patternRepeatX = true;
} else if (repetition == QStringLiteral("repeat-y")) {
pattern->patternRepeatY = true;
} else if (repetition == QStringLiteral("no-repeat")) {
pattern->patternRepeatY = false;
pattern->patternRepeatY = false;
} else {
//TODO: exception: SYNTAX_ERR
}
....
}
PVS-Studio warning: V519 The 'pattern-> patternRepeatY' variable is assigned values twice successively. Perhaps this is a mistake. Check lines: 1775, 1776. qquickcontext2d.cpp 1776
Two times in a row the variable 'patternRepeatY' is assigned:
pattern->patternRepeatY = false;
pattern->patternRepeatY = false;
I think it should be written here:
} else if (repetition == QStringLiteral("no-repeat")) {
pattern->patternRepeatX = false;
pattern->patternRepeatY = false;
} else {
Misuse of C ++

As I said, most errors are ordinary typos. There are almost no errors associated with improper use of the C ++ language. But a couple of such errors were still found.
Beautiful error related to operation priority
bool QConfFileSettingsPrivate::readIniLine(....)
{
....
char ch;
while (i < dataLen &&
((ch = data.at(i) != '\n') && ch != '\r'))
++i;
....
}
V593 Consider reviewing the expression of the 'A = B! = C' kind. The expression is calculated as following: 'A = (B! = C)'. qsettings.cpp 1702
The loop is designed to find the end of a line. The end of line character is the character '\ n' or '\ r'.
Inside the condition, a character must be taken and compared with '\ n' and '\ r'. The error occurs because the priority of the '! =' Operator is higher than the operator '='. Because of this, it is not the character code that is written to the variable 'ch', but 'true' or 'false'. As a result, the comparison '\ r' no longer plays a role.
We place the brackets so that the error is better noticeable:
while (i < dataLen &&
((ch = (data.at(i) != '\n')) && ch != '\r'))
Due to an error, only the '\ n' character is considered the end of the line. If the lines end with the character '\ r', the function will not work correctly.
The correct code is:
while (i < dataLen &&
(ch = data.at(i)) != '\n' && ch != '\r')
Loss of accuracy
bool QWindowsTabletSupport::translateTabletPacketEvent()
{
....
const double radAzim =
(packet.pkOrientation.orAzimuth / 10) * (M_PI / 180);
....
}
V636 The 'packet.pkOrientation.orAzimuth / 10' expression was implicitly casted from 'int' type to 'double' type. Consider utilizing an explicit type cast to avoid the loss of a fractional part. An example: double A = (double) (X) / Y ;. qwindowstabletsupport.cpp 467 The
variable 'packet.pkOrientation.orAzimuth' is of type 'int'. This integer variable is divided by the number 10. It is suspicious that then the result of division is used together with the values of type 'double'. The final result is also placed in a variable of type 'double'.
Such integer division is not necessarily a mistake. Perhaps the code is written exactly as intended. But as practice shows, often this is a flaw, leading to a loss in accuracy of calculations.
For example, let the variable 'packet.pkOrientation.orAzimuth' be 55. Then the result of the calculations will be:
( 55/10 ) * (3.14159 ... / 180) = 5 * 0.01745 ... = 0.087266 ... The
accuracy can be significantly increased. It is enough to declare constant 10 as a double type: "(packet.pkOrientation.orAzimuth / 10.0 ) * (M_PI / 180)". Now the result of the calculations is:
(55 / 10.0) * (3.14159 ... / 180) = 5.5 * 0,01745 ... = 0,095993 ...
Such inaccuracies often occur, since programmers are inattentive to expressions where variables of different types are mixed. Such inattention often also leads to 64-bit errors (see mixed arithmetic ).
The analyzer detects another 51 suspicious integer divisions. Perhaps some of the expressions will be less accurate than the developers wanted. I list them: qt-v636.txt .
Pointless pointer checks
If memory is allocated using the 'new' operator, it has long been pointless to check the pointer for equality to zero. If memory cannot be allocated, an exception will be thrown. Of course, you can make the operator 'new' return 0, but now we are not talking about these cases.
However, from time to time, programmers forget, and a meaningless check reappears in the code.
HRESULT STDMETHODCALLTYPE QWindowsEnumerate::Clone(
IEnumVARIANT **ppEnum)
{
QWindowsEnumerate *penum = 0;
*ppEnum = 0;
penum = new QWindowsEnumerate(array);
if (!penum)
return E_OUTOFMEMORY;
....
}
PVS-Studio Warning: V668 There is no sense in testing the 'penum' pointer against null, as the memory was allocated using the 'new' operator. The exception will be generated in the case of memory allocation error. qwindowsmsaaaccessible.cpp 141
There are several more of these checks: main.cpp 127, qaudiodevicefactory.cpp 236, qaudiodevicefactory.cpp 263, qaudiobuffer.cpp 488, mfvideorenderercontrol.cpp 143, mfvideorenderercontrol.cvpppreferendorcontrol.cvpppprerer, mcpppprerer, mcppprerer, mcvpprefrev, qaxserverbase.cpp 1006, positionpollfactory.cpp 60.
Dark side

There are two pieces of code about which I cannot say that this is definitely a mistake. I do not know the architecture of the project and the features of implementation. However, even if these are not errors, then this is the dark side of C ++ programming.
class Q_CORE_EXPORT QObject
{
....
virtual ~QObject();
virtual bool event(QEvent *);
virtual bool eventFilter(QObject *, QEvent *);
....
};
QObject *QQmlVME::run(....)
{
....
QObject *o = (QObject *)operator
new(instr.typeSize + sizeof(QQmlData));
::memset(static_cast(o), 0,
instr.typeSize + sizeof(QQmlData));
....
}
PVS-Studio Warning: V598 The 'memset' function is used to nullify the fields of 'QObject' class. Virtual method table will be damaged by this. qqmlvme.cpp 658
The QObject class has virtual functions. This means that the object stores a pointer to a table of virtual methods. It seems to me not a good idea to initialize such objects using the memset () function.
Another warning: V598 The 'memset' function is used to nullify the fields of 'QObject' class. Virtual method table will be damaged by this. qdeclarativevme.cpp 286
Dereferencing null pointers
Perhaps these errors could be attributed to typos. But I like to separate them into a separate group. So they seem darker and more serious.
Note. The division of errors into groups is always fairly arbitrary. Often the same error can be classified as a typo, as a vulnerability, as going out of bounds of an array, and so on.
Let's go back to the null pointers.
Typo dereferencing due to typo
QV4::ReturnedValue QQuickJSContext2DPixelData::getIndexed(
QV4::Managed *m, uint index, bool *hasProperty)
{
....
if (!m)
return m->engine()->currentContext()->throwTypeError();
....
}
PVS-Studio Warning: V522 Dereferencing of the null pointer 'm' might take place. qquickcontext2d.cpp 3169
Apparently, the operator '!' here is superfluous. A simple typo leading to a serious mistake.
Null pointer dereference in an error handler
void QDocIndexFiles::readIndexSection(....)
{
....
DocNode* dn = qdb_->findGroup(groupNames[i]);
if (dn) {
dn->addMember(node);
}
else {
....
qDebug() << "DID NOT FIND GROUP:" << dn->name()
<< "for:" << node->name();
}
....
}
PVS-Studio Warning: V522 Dereferencing of the null pointer 'dn' might take place. qdocindexfiles.cpp 539
If an error occurs, a diagnostic message should be printed. They will try to take a name from a nonexistent object in it: dn-> name ().
82 potential dereferencing of the null pointer
In almost all projects, including Qt, there are flaws in working with null pointers. Often, verification is carried out after the pointer has been used. This is not always a mistake. It happens that a pointer, in principle, cannot be equal to zero.
In any case, such places deserve to be studied and refactored. Even if there is no error, an extra check on the pointer confuses the programmer when reading the code.
Consider one of the fragments of dangerous code:
static int gray_raster_render(....)
{
const QT_FT_Outline* outline =
(const QT_FT_Outline*)params->source;
....
/* return immediately if the outline is empty */
if ( outline->n_points == 0 || outline->n_contours <= 0 )
return 0;
if ( !outline || !outline->contours || !outline->points )
return ErrRaster_Invalid_Outline;
....
}
PVS-Studio Warning: V595 The 'outline' pointer was utilized before it was verified against nullptr. Check lines: 1746, 1749. qgrayraster.c 1746
I think the error appeared at the moment when they wanted to optimize the gray_raster_render () function. Most likely, in the already completed function code, these lines were inserted:
/* return immediately if the outline is empty */
if ( outline->n_points == 0 || outline->n_contours <= 0 )
return 0;
The trouble is that the 'outline' pointer may turn out to be null. Checking that the pointer is zero is a little lower.
The analyzer found another 81 potential errors. Let me give you a list of diagnostic messages: qt-v595.txt .
Unanswered questions

There are strange code fragments that are hard to tell about how they appeared and what was actually planned to be written. Perhaps these are typos, possibly incomplete code, possibly unsuccessful refactoring.
Double check
QWindowsFontEngine::~QWindowsFontEngine()
{
....
if (QWindowsContext::verboseFonts)
if (QWindowsContext::verboseFonts)
qDebug("%s: font='%s", __FUNCTION__, qPrintable(_name));
....
}
PVS-Studio Warning: V571 Recurring check. The 'if (QWindowsContext :: verboseFonts)' condition was already verified in line 369. qwindowsfontengine.cpp 370
Why double-check the same thing? Perhaps one check is unnecessary. Perhaps they forgot to check something else.
Double assignment
void Moc::parse()
{
....
index = def.begin + 1;
namespaceList += def;
index = rewind;
....
}
PVS-Studio Warning: V519 The 'index' variable is assigned values twice successively. Perhaps this is a mistake. Check lines: 568, 570. moc.cpp 570
Why are the 'index' variable assigned different values?
There are a few other similar weird code snippets:
- V519 The 'exitCode' variable is assigned values twice successively. Perhaps this is a mistake. Check lines: 807, 815. qprocess.cpp 815
- V519 The 'detecting' variable is assigned values twice successively. Perhaps this is a mistake. Check lines: 163, 164. qhoversensorgesturerecognizer.cpp 164
- V519 The 'increaseCount' variable is assigned values twice successively. Perhaps this is a mistake. Check lines: 185, 186. qtwistsensorgesturerecognizer.cpp 186
bool GSuggestCompletion::eventFilter(QObject *obj, QEvent *ev)
{
....
switch (key) {
case Qt::Key_Enter:
case Qt::Key_Return:
doneCompletion();
consumed = true;
case Qt::Key_Escape:
editor->setFocus();
popup->hide();
consumed = true;
case Qt::Key_Up:
case Qt::Key_Down:
case Qt::Key_Home:
case Qt::Key_End:
case Qt::Key_PageUp:
case Qt::Key_PageDown:
break;
....
}
PVS-Studio Warning: V519 The 'consumed' variable is assigned values twice successively. Perhaps this is a mistake. Check lines: 110, 115. googlesuggest.cpp 115 Is the
break statement forgotten here or not?
It seemed strange to the analyzer that the variable 'consumed' could be assigned the value 'true' two times in a row. It is likely that the break statement is forgotten here. But I'm not so sure. Perhaps you just need to remove the first assignment: "consumed = true;".
Suspicion of an extra 'break' statement
bool QHelpGenerator::registerVirtualFolder(....)
{
....
while (d->query->next()) {
d->namespaceId = d->query->value(0).toInt();
break;
}
....
}
PVS-Studio Warning: V612 An unconditional 'break' within a loop. qhelpgenerator.cpp 429
Is it correct that the loop will stop immediately due to the 'break' statement?
Another such piece of code lives here: qhelpgenerator.cpp 642
Miscellaneous
Be patient. The article will end soon. There are still a few motley errors.
Incorrect use of the toLower () function
int main(int argc, char **argv)
{
....
QByteArray arg(argv[a]);
....
arg = arg.mid(1);
arg.toLower();
if (arg == "o")
....
}
PVS-Studio Warning: V530 The return value of function 'toLower' is required to be utilized. main.cpp 72
The 'toLower ()' function does not modify the object. It returns a copy of the object, which will store lowercase characters.
Another mistake: V530 The return value of function 'toLower' is required to be utilized. main.cpp 1522
Going beyond the bounds of the array
The situation is complicated. Please concentrate.
There is such a numbered type:
typedef enum {
JNone,
JCausing,
JDual,
JRight,
JTransparent
} Joining;
Remember that JTransparent == 4.
Now let's look at the getNkoJoining () function:
static Joining getNkoJoining(unsigned short uc)
{
if (uc < 0x7ca)
return JNone;
if (uc <= 0x7ea)
return JDual;
if (uc <= 0x7f3)
return JTransparent;
if (uc <= 0x7f9)
return JNone;
if (uc == 0x7fa)
return JCausing;
return JNone;
}
What matters to us is that this function can return 'JTransparent'. That is, the function can return 4.
The program has a two-dimensional array 'joining_table':
static const JoiningPair joining_table[5][4] = { .... };
And now the actual place where the error may occur:
static void getNkoProperties(....)
{
....
Joining j = getNkoJoining(chars[0]);
ArabicShape shape = joining_table[XIsolated][j].form2;
....
}
PVS-Studio Warning: V557 Array overrun is possible. The value of 'j' index could reach 4. harfbuzz-arabic.c 516
As we recall, the getNkoJoining () function can return a value of 4. Thus, we refer to the cell of the joining_table [...] [4] array. It is unacceptable. The array will go beyond the bounds of the array.
Same conditions
void Node::setPageType(const QString& t)
{
if ((t == "API") || (t == "api"))
pageType_ = ApiPage;
else if (t == "howto")
pageType_ = HowToPage;
else if (t == "overview")
pageType_ = OverviewPage;
else if (t == "tutorial")
pageType_ = TutorialPage;
else if (t == "howto")
pageType_ = HowToPage;
else if (t == "article")
pageType_ = ArticlePage;
else if (t == "example")
pageType_ = ExamplePage;
else if (t == "ditamap")
pageType_ = DitaMapPage;
}
PVS-Studio warning: V517 The use of 'if (A) {...} else if (A) {...}' pattern was detected. There is a probability of logical error presence. Check lines: 386, 392. node.cpp 386
The check is performed two times (t == "howto"). I think one of them is superfluous.
Here are a couple more similar warnings:
- V517 The use of 'if (A) {...} else if (A) {...}' pattern was detected. There is a probability of logical error presence. Check lines: 188, 195. qmaintainingreader_tpl_p.h 188
- V517 The use of 'if (A) {...} else if (A) {...}' pattern was detected. There is a probability of logical error presence. Check lines: 299, 303. mfmetadatacontrol.cpp 299
void
QBluetoothServiceDiscoveryAgentPrivate::_q_deviceDiscovered(
const QBluetoothDeviceInfo &info)
{
if(mode == QBluetoothServiceDiscoveryAgent::FullDiscovery) {
for(int i = 0; i < discoveredDevices.count(); i++){
if(discoveredDevices.at(i).address() == info.address()){
discoveredDevices.removeAt(i);
}
}
discoveredDevices.prepend(info);
}
else {
for(int i = 0; i < discoveredDevices.count(); i++){
if(discoveredDevices.at(i).address() == info.address()){
discoveredDevices.removeAt(i);
}
}
discoveredDevices.prepend(info);
}
}
PVS-Studio Warning: V523 The 'then' statement is equivalent to the 'else' statement. qbluetoothservicediscoveryagent.cpp 402
Regardless of the condition, the same actions are performed.
Similarly: pcre_exec.c 5577, ditaxmlgenerator.cpp 1722, htmlgenerator.cpp 388.
Inherited Errors
Qt uses several third-party libraries. These libraries also have errors. It turns out that these errors are also in Qt. I did not describe them in the article, but decided that I could mention them.
I did not look carefully at the third-party libraries, but wrote out something: qt-3rdparty.txt .
Note. However, you should not think that I watched Qt very carefully. A project of a large and even superficial inspection is enough to write such an article.
conclusions
PVS-Studio is an excellent, powerful analyzer that is able to find errors even in such high-quality and sleek projects as the Qt framework.
It will help save a lot of time for the development team by detecting many errors at an early stage. If you use incremental analysis , errors will be detected immediately after compiling the files.
Sitelinks
- We regularly check open-source projects. For example, Tor, Chromium, Clang, Firebird, OpenCV. Everyone who is interested, come here: "An updated list of open-source projects that we tested using PVS-Studio ."
- Here you can download a trial version of PVS-Studio . At the beginning, there are 20 clicks to navigate through the alerts. After reporting information about yourself, another 200 clicks.
This article is in English.
If you want to share this article with an English-speaking audience, then please use the link to the translation: Andrey Karpov. Checking the Qt 5 Framework .

Have you read the article and have a question?
Often our articles are asked the same questions. We collected answers to them here: Answers to questions from readers of articles about PVS-Studio and CppCat, version 2014 . Please see the list.