New C++/Qt code checks in clazy static analyzer
About two months ago I blogged about clazy, a Qt oriented static analyser.
Since then it has moved to an official KDE repo http://anongit.kde.org/clazy, got an IRC channel (#kde-clazy @ freenode) and also many fun new checks.
Here's a quick dump of the new features (be sure to see the README for the old checks too):
**** Performance related checks ****
qstring-arg: (saves allocations)
s5 = QString("%1 %2 %3 %4").arg(s).arg(s1).arg(s3, s4);
main.cpp: warning: Use multi-arg instead [-Wclazy-qstring-arg]
qstring-ref: (saves allocations, fixit included)
int n = str.mid(1, 1).toInt(&ok);
main.cpp: warning: Use midRef() instead [-Wclazy-qstring-ref]
qdatetime-utc: (saves allocations)
QDateTime::currentDateTime().toUTC();
main.cpp: warning: Use QDateTime::currentDateTimeUtc() instead [-Wclazy-qdatetime-utc]
qgetenv (saves allocations):
qgetenv("Foo").isEmpty();
main.cpp: warning: qgetenv().isEmpty() allocates. Use qEnvironmentVariableIsEmpty() instead [-Wclazy-qgetenv]
range-loop:
for (int i : getQtList()) {
range-loop.cpp warning: c++11 range-loop might detach Qt container [-Wclazy-foreach]
foreach:
foreach (int i, v) {
main.cpp: warning: foreach with STL container causes deep-copy [-Wclazy-foreach]
old-style-connect:
connect(ptr, SIGNAL(signal1()), SLOT(slot1()));
main.cpp: warning: Old Style Connect [-Wclazy-old-style-connect]
qDeleteAll:
qDeleteAll(s.values());
main.cpp: warning: Calling qDeleteAll with QSet::values, call qDeleteAll on the container itself [-Wclazy-qdeleteall]
**** Crash related checks ****
temporary-iterator:
for (auto it = getList().begin(); it != getList().end(); ++it) {}
main.cpp: warning: Don't call QList::end() on temporary [-Wclazy-temporary-iterator]
auto-unexpected-qstringbuilder:
const auto s1 = "tests/" + QString::fromLatin1("foo");
main.cpp: warning: auto deduced to be QStringBuilder instead of QString. Possible crash. [-Wclazy-auto-unexpected-qstringbuilder]
**** Misc related checks ****
writing-to-temporary:
widget->sizePolicy().setVerticalStretch(1);
main.cpp: warning: Call to temporary is a no-op: QSizePolicy::setVerticalStretch [-Wclazy-writing-to-temporary]
implicit-casts:
explicit ComposerLineEdit(bool useCompletion, QWidget *parent = Q_NULLPTR);
RecipientLineEdit::RecipientLineEdit(QWidget *parent) : ComposerLineEdit(parent) <-- oops, passing pointer as firt argument, which is a bool
main.cpp warning: Implicit pointer to bool cast (argument 1) [-Wclazy-implicit-casts]
Also, old-style-connect and qstring-ref checks got fixits, so you can fix your code just by recompiling it with clazy.
Big thanks to everyone who contributed ideas and even code!
Please report bugs at b.k.o, happy hacking!