diff options
author | Sergio Martins <smartins@kde.org> | 2018-03-08 20:15:07 +0000 |
---|---|---|
committer | Sergio Martins <smartins@kde.org> | 2018-03-11 21:32:38 +0000 |
commit | 34bcfc8677ffe7063b553af1a0a4ab5b94729c70 (patch) | |
tree | e65ed0acf4dffc8af7a473eb61d6a6a349df523e | |
parent | 6e05abc60870316f8e6d00b9e879891518739af5 (diff) |
Introduce wrong-qevent-cast
Warns when QEvents are cast to possibly the wrong class
-rw-r--r-- | Changelog | 1 | ||||
-rw-r--r-- | CheckSources.cmake | 1 | ||||
-rw-r--r-- | README.md | 1 | ||||
-rw-r--r-- | checks.json | 6 | ||||
-rw-r--r-- | src/Checks.h | 2 | ||||
-rw-r--r-- | src/HierarchyUtils.h | 9 | ||||
-rw-r--r-- | src/checks/level0/README-wrong-qevent-cast.md | 11 | ||||
-rw-r--r-- | src/checks/level0/wrong-qevent-cast.cpp | 274 | ||||
-rw-r--r-- | src/checks/level0/wrong-qevent-cast.h | 39 | ||||
-rw-r--r-- | tests/clazy/test_requested_checks.sh.expected | 33 | ||||
-rw-r--r-- | tests/wrong-qevent-cast/config.json | 7 | ||||
-rw-r--r-- | tests/wrong-qevent-cast/main.cpp | 41 | ||||
-rw-r--r-- | tests/wrong-qevent-cast/main.cpp.expected | 3 |
13 files changed, 412 insertions, 16 deletions
@@ -74,6 +74,7 @@ unneeded-cast qt-keywords, with fixit included qhash-with-char-pointer-key + wrong-qevent-cast - auto-unexpected-qstringbuilder now also warns for lambdas returning QStringBuilder - performance optimizations - Added -header-filter=<regex> option to clazy-standalone. Only headers matching the regexp will have warnings, diff --git a/CheckSources.cmake b/CheckSources.cmake index b07cb600..b73840c3 100644 --- a/CheckSources.cmake +++ b/CheckSources.cmake @@ -31,6 +31,7 @@ set(CLAZY_CHECKS_SRCS ${CLAZY_CHECKS_SRCS} ${CMAKE_CURRENT_LIST_DIR}/src/checks/level0/temporary-iterator.cpp ${CMAKE_CURRENT_LIST_DIR}/src/checks/level0/unused-non-trivial-variable.cpp ${CMAKE_CURRENT_LIST_DIR}/src/checks/level0/writing-to-temporary.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/checks/level0/wrong-qevent-cast.cpp ${CMAKE_CURRENT_LIST_DIR}/src/checks/level0/wrong-qglobalstatic.cpp ${CMAKE_CURRENT_LIST_DIR}/src/checks/level1/auto-unexpected-qstringbuilder.cpp ${CMAKE_CURRENT_LIST_DIR}/src/checks/level1/child-event-qobject-cast.cpp @@ -250,6 +250,7 @@ clazy runs all checks from level1 by default. - [temporary-iterator](src/checks/level0/README-temporary-iterator.md) - [unused-non-trivial-variable](src/checks/level0/README-unused-non-trivial-variable.md) - [writing-to-temporary](src/checks/level0/README-writing-to-temporary.md) + - [wrong-qevent-cast](src/checks/level0/README-wrong-qevent-cast.md) - [wrong-qglobalstatic](src/checks/level0/README-wrong-qglobalstatic.md) - Checks from Level 1: diff --git a/checks.json b/checks.json index 5606ce6a..c249df70 100644 --- a/checks.json +++ b/checks.json @@ -73,6 +73,12 @@ "visits_stmts" : true }, { + "name" : "wrong-qevent-cast", + "level" : 0, + "categories" : ["bug"], + "visits_stmts" : true + }, + { "name" : "lambda-in-connect", "level" : 0, "categories" : ["bug"], diff --git a/src/Checks.h b/src/Checks.h index b819036c..3ee51d76 100644 --- a/src/Checks.h +++ b/src/Checks.h @@ -59,6 +59,7 @@ #include "checks/level0/temporary-iterator.h" #include "checks/level0/unused-non-trivial-variable.h" #include "checks/level0/writing-to-temporary.h" +#include "checks/level0/wrong-qevent-cast.h" #include "checks/level0/wrong-qglobalstatic.h" #include "checks/level1/auto-unexpected-qstringbuilder.h" #include "checks/level1/child-event-qobject-cast.h" @@ -147,6 +148,7 @@ void CheckManager::registerChecks() registerCheck(check<TemporaryIterator>("temporary-iterator", CheckLevel0, RegisteredCheck::Option_VisitsStmts)); registerCheck(check<UnusedNonTrivialVariable>("unused-non-trivial-variable", CheckLevel0, RegisteredCheck::Option_VisitsStmts)); registerCheck(check<WritingToTemporary>("writing-to-temporary", CheckLevel0, RegisteredCheck::Option_VisitsStmts)); + registerCheck(check<WrongQEventCast>("wrong-qevent-cast", CheckLevel0, RegisteredCheck::Option_VisitsStmts)); registerCheck(check<WrongQGlobalStatic>("wrong-qglobalstatic", CheckLevel0, RegisteredCheck::Option_VisitsStmts)); registerCheck(check<AutoUnexpectedQStringBuilder>("auto-unexpected-qstringbuilder", CheckLevel1, RegisteredCheck::Option_VisitsStmts | RegisteredCheck::Option_VisitsDecls)); registerFixIt(1, "fix-auto-unexpected-qstringbuilder", "auto-unexpected-qstringbuilder"); diff --git a/src/HierarchyUtils.h b/src/HierarchyUtils.h index 0db7f548..bef0cbba 100644 --- a/src/HierarchyUtils.h +++ b/src/HierarchyUtils.h @@ -118,6 +118,10 @@ T* getFirstChildOfType2(clang::Stmt *stm) if (clazy::hasChildren(stm)) { auto child = *(stm->child_begin()); + + if (!child) // can happen + return nullptr; + if (auto s = clang::dyn_cast<T>(child)) return s; @@ -265,6 +269,11 @@ T* unpeal(clang::Stmt *stmt, IgnoreStmts options = IgnoreNone) return nullptr; } +inline clang::SwitchStmt* getSwitchFromCase(clang::ParentMap *pmap, clang::CaseStmt *caseStm) +{ + return getFirstParentOfType<clang::SwitchStmt>(pmap, caseStm); +} + } #endif diff --git a/src/checks/level0/README-wrong-qevent-cast.md b/src/checks/level0/README-wrong-qevent-cast.md new file mode 100644 index 00000000..96244231 --- /dev/null +++ b/src/checks/level0/README-wrong-qevent-cast.md @@ -0,0 +1,11 @@ +# wrong-qevent-cast + +Warns when a QEvent is possibly cast to the wrong derived class via static_cast. + +Example: +switch (ev->type()) { + case QEvent::MouseMove: + auto e = static_cast<QKeyEvent*>(ev); +} + +Currently only casts inside switches are verified. diff --git a/src/checks/level0/wrong-qevent-cast.cpp b/src/checks/level0/wrong-qevent-cast.cpp new file mode 100644 index 00000000..d61a10d7 --- /dev/null +++ b/src/checks/level0/wrong-qevent-cast.cpp @@ -0,0 +1,274 @@ +/* + This file is part of the clazy static checker. + + Copyright (C) 2018 Sergio Martins <smartins@kde.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "wrong-qevent-cast.h" +#include "Utils.h" +#include "HierarchyUtils.h" +#include "QtUtils.h" +#include "TypeUtils.h" +#include "ClazyContext.h" + +#include <clang/AST/AST.h> +#include <unordered_map> + +using namespace clang; +using namespace std; + +typedef vector<StringRef> ClassNameList; + +enum QtUnregularlyNamedEventTypes { + DragEnter = 60, + DragLeave = 62, + OrientationChange = 208, + ActionAdded = 114, + ActionRemoved = 115, + ActionChanged = 99, + ChildAdded = 68, + ChildRemoved = 71, + ChildPolished = 69, + MouseButtonPress = 2, + MouseButtonRelease = 3, + MouseButtonDblClick = 4, + MouseMove = 5, + NonClientAreaMouseMove = 173, + NonClientAreaMouseButtonPress = 174, + NonClientAreaMouseButtonRelease = 175, + NonClientAreaMouseButtonDblClick = 176, + FocusIn = 8, + FocusOut = 9, + FocusAboutToChange = 23, + Gesture = 198, + GestureOverride = 202, + HoverEnter = 127, + HoverLeave = 128, + HoverMove = 129, + TabletEnterProximity = 171, + TabletLeaveProximity = 172, + TabletPress = 92, + TabletMove = 87, + TabletRelease = 93, + ToolTip = 110, + Wheel = 31, + KeyPress = 6, + KeyRelease = 7, + ShortcutOverride = 51, + DragMove = 61, + GraphicsSceneMouseMove = 155, + GraphicsSceneMousePress = 156, + GraphicsSceneMouseRelease = 157, + GraphicsSceneMouseDoubleClick = 158, + GraphicsSceneContextMenu = 159, + GraphicsSceneHoverEnter = 160, + GraphicsSceneHoverMove = 161, + GraphicsSceneHoverLeave = 162, + GraphicsSceneHelp = 163, + GraphicsSceneDragEnter = 164, + GraphicsSceneDragMove = 165, + GraphicsSceneDragLeave = 166, + GraphicsSceneDrop = 167, + GraphicsSceneWheel = 168, + GraphicsSceneResize = 181, + TouchBegin = 194, + TouchEnd = 196, + TouchCancel = 209, + TouchUpdate = 195, + NativeGesture = 197, + MetaCall = 43, + WhatsThis = 111, + ContextMenu = 82, + QueryWhatsThis = 123 + // StatusTip = 112 not irregular, but qtbase casts it to QHelpEvent for some reason, needs investigation +}; + + +WrongQEventCast::WrongQEventCast(const std::string &name, ClazyContext *context) + : CheckBase(name, context) +{ + + +} + +static bool eventTypeMatchesClass(QtUnregularlyNamedEventTypes eventType, string eventTypeStr, StringRef className) +{ + // In the simplest case, the class is "Q" + eventType + "Event" + string expectedClassName = string("Q") + eventTypeStr + string("Event"); + if (expectedClassName == className) + return true; + + // Otherwise it's unregular and we need a map: + + static unordered_map<QtUnregularlyNamedEventTypes, ClassNameList> map = { + { ActionAdded, {"QActionEvent" } }, + { ActionRemoved, {"QActionEvent" } }, + { ActionChanged, {"QActionEvent" } }, + { ChildAdded, {"QChildEvent" } }, + { ChildRemoved, {"QChildEvent" } }, + { ChildPolished, {"QChildEvent" } }, + { MetaCall, {"QDBusSpyCallEvent", "QDBusCallDeliveryEvent"} }, + { DragEnter, {"QDragEnterEvent", "QDragMoveEvent", "QDropEvent" } }, + { DragLeave, {"QDragLeaveEvent", "QDragMoveEvent", "QDropEvent" } }, + { DragMove, {"QDragMoveEvent", "QDropEvent" } }, + { FocusIn, {"QFocusEvent" } }, + { FocusOut, {"QFocusEvent" } }, + { FocusAboutToChange, {"QFocusEvent" } }, + { Gesture, {"QGestureEvent" } }, + { GestureOverride, {"QGestureEvent" } }, + { GraphicsSceneContextMenu, {"QGraphicsSceneEvent" } }, + { GraphicsSceneHoverEnter, { "QGraphicsSceneHoverEvent", "QGraphicsSceneEvent" } }, + { GraphicsSceneHoverMove, {"QGraphicsSceneHoverEvent", "QGraphicsSceneEvent" } }, + { GraphicsSceneHoverLeave, {"QGraphicsSceneHoverEvent", "QGraphicsSceneEvent" } }, + { GraphicsSceneHelp, { "QGraphicsSceneEvent" } }, + { GraphicsSceneDragEnter, {"QGraphicsSceneDragDropEvent", "QGraphicsSceneEvent" } }, + { GraphicsSceneDragMove, {"QGraphicsSceneDragDropEvent", "QGraphicsSceneEvent" } }, + { GraphicsSceneDragLeave, {"QGraphicsSceneDragDropEvent", "QGraphicsSceneEvent" } }, + { GraphicsSceneDrop, {"QGraphicsSceneDragDropEvent", "QGraphicsSceneEvent" } }, + { GraphicsSceneWheel, {"QGraphicsSceneEvent" } }, + { GraphicsSceneResize, {"QGraphicsSceneEvent" } }, + { GraphicsSceneMouseMove, {"QGraphicsSceneMouseEvent" } }, + { GraphicsSceneMousePress, {"QGraphicsSceneMouseEvent" } }, + { GraphicsSceneMouseRelease, {"QGraphicsSceneMouseEvent" } }, + { GraphicsSceneMouseDoubleClick, {"QGraphicsSceneMouseEvent" } }, + //{ StatusTip, {"QStatusTipEvent" } }, + { ToolTip, {"QHelpEvent" } }, + { WhatsThis, {"QHelpEvent" } }, + { QueryWhatsThis, {"QHelpEvent" } }, + { HoverEnter, {"QHoverEvent", "QInputEvent" } }, + { HoverLeave, {"QHoverEvent", "QInputEvent" } }, + { HoverMove, {"QHoverEvent", "QInputEvent" } }, + { KeyPress, {"QKeyEvent", "QInputEvent" } }, + { KeyRelease, {"QKeyEvent", "QInputEvent" } }, + { ShortcutOverride, {"QKeyEvent", "QInputEvent" } }, + { MouseButtonPress, {"QMouseEvent" } }, + { MouseButtonRelease, {"QMouseEvent" } }, + { MouseButtonDblClick, {"QMouseEvent" } }, + { MouseMove, {"QMouseEvent" } }, + { NonClientAreaMouseMove, {"QMouseEvent" } }, + { NonClientAreaMouseButtonPress, {"QMouseEvent" } }, + { NonClientAreaMouseButtonRelease, {"QMouseEvent" } }, + { NonClientAreaMouseButtonRelease, {"QMouseEvent" } }, + { NonClientAreaMouseButtonDblClick, {"QMouseEvent" } }, + { NativeGesture, { "QInputEvent" } }, + { OrientationChange, {"QScreenOrientationChangeEvent" } }, + { TabletEnterProximity, {"QTabletEvent", "QInputEvent" } }, + { TabletLeaveProximity, {"QTabletEvent", "QInputEvent" } }, + { TabletPress, {"QTabletEvent", "QInputEvent" } }, + { TabletMove, {"QTabletEvent", "QInputEvent" } }, + { TabletRelease, {"QTabletEvent", "QInputEvent" } }, + { TouchBegin, {"QTouchEvent", "QInputEvent" } }, + { TouchCancel, {"QTouchEvent", "QInputEvent" } }, + { TouchEnd, {"QTouchEvent", "QInputEvent" } }, + { TouchUpdate, {"QTouchEvent", "QInputEvent" } }, + { Wheel, {"QInputEvent" } }, + { ContextMenu, {"QInputEvent" } } + }; + + auto it = map.find(eventType); + if (it == map.cend()) + return false; + + const ClassNameList &classes = it->second; + const bool found = clazy::find(classes, className) != classes.cend(); + + return found; +} + + +// TODO: Use iterators +CaseStmt* getCaseStatement(clang::ParentMap *pmap, Stmt *stmt, DeclRefExpr *event) +{ + Stmt *s = pmap->getParent(stmt); + + while (s) { + + if (auto ifStmt = dyn_cast<IfStmt>(s)) { + // if there's we're inside an if statement then skip, to avoid false-positives + auto declRef = clazy::getFirstChildOfType2<DeclRefExpr>(ifStmt->getCond()); + if (declRef && declRef->getDecl() == event->getDecl()) + return nullptr; + } + + + if (auto caseStmt = dyn_cast<CaseStmt>(s)) { + auto switchStmt = clazy::getSwitchFromCase(pmap, caseStmt); + if (switchStmt) { + auto declRef = clazy::getFirstChildOfType2<DeclRefExpr>(switchStmt->getCond()); + + llvm::errs() << "Found a switch statement " << switchStmt << "with declref" << declRef << "; " << event << "\n"; + switchStmt->getCond()->dump(); + + // Does this switch refer to the same QEvent ? + if (declRef && declRef->getDecl() == event->getDecl()) + return caseStmt; + } + } + + s = pmap->getParent(s); + } + + return nullptr; +} + +void WrongQEventCast::VisitStmt(clang::Stmt *stmt) +{ + auto cast = dyn_cast<CXXStaticCastExpr>(stmt); + if (!cast) + return; + + Expr *e = cast->getSubExpr(); + + QualType t = e ? e->getType() : QualType(); + QualType pointeeType = t.isNull() ? QualType() : TypeUtils::pointeeQualType(t); + CXXRecordDecl *rec = pointeeType.isNull() ? nullptr : pointeeType->getAsCXXRecordDecl(); + + if (!rec || clazy::name(rec) != "QEvent") + return; + + CXXRecordDecl *castTo = Utils::namedCastOuterDecl(cast); + if (!castTo) + return; + + auto declref = clazy::getFirstChildOfType2<DeclRefExpr>(cast->getSubExpr()); + if (!declref) + return; + + auto caseStmt = getCaseStatement(m_context->parentMap, stmt, declref); + if (!caseStmt) + return; + + auto caseValue = clazy::getFirstChildOfType2<DeclRefExpr>(caseStmt->getLHS()); + if (!caseValue) + return; + + + auto enumeratorDecl = dyn_cast<EnumConstantDecl>(caseValue->getDecl()); + if (!enumeratorDecl) + return; + + auto enumeratorVal = static_cast<QtUnregularlyNamedEventTypes>(enumeratorDecl->getInitVal().getExtValue()); + + string eventTypeStr = enumeratorDecl->getNameAsString(); + StringRef castToName = clazy::name(castTo); + + if (eventTypeMatchesClass(enumeratorVal, eventTypeStr, castToName)) + return; + + emitWarning(stmt, string("Cast from a QEvent::") + eventTypeStr + " event to " + string(castToName) + " looks suspicious."); +} diff --git a/src/checks/level0/wrong-qevent-cast.h b/src/checks/level0/wrong-qevent-cast.h new file mode 100644 index 00000000..043cdb82 --- /dev/null +++ b/src/checks/level0/wrong-qevent-cast.h @@ -0,0 +1,39 @@ +/* + This file is part of the clazy static checker. + + Copyright (C) 2018 Sergio Martins <smartins@kde.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef CLAZY_WRONG_QEVENT_CAST_H +#define CLAZY_WRONG_QEVENT_CAST_H + +#include "checkbase.h" + + +/** + * See README-wrong-qevent-cast.md for more info. + */ +class WrongQEventCast : public CheckBase +{ +public: + explicit WrongQEventCast(const std::string &name, ClazyContext *context); + void VisitStmt(clang::Stmt *) override; +private: +}; + +#endif diff --git a/tests/clazy/test_requested_checks.sh.expected b/tests/clazy/test_requested_checks.sh.expected index 1c8d5e14..132471b6 100644 --- a/tests/clazy/test_requested_checks.sh.expected +++ b/tests/clazy/test_requested_checks.sh.expected @@ -1,6 +1,6 @@ -Requested checks: auto-unexpected-qstringbuilder, child-event-qobject-cast, connect-3arg-lambda, connect-by-name, connect-non-signal, connect-not-normalized, const-signal-or-slot, container-anti-pattern, detaching-temporary, foreach, fully-qualified-moc-types, incorrect-emit, inefficient-qlist-soft, install-event-filter, lambda-in-connect, lambda-unique-connection, mutable-container-key, non-pod-global-static, overridden-signal, post-event, qcolor-from-literal, qdatetime-utc, qdeleteall, qenums, qfileinfo-exists, qgetenv, qhash-namespace, qlatin1string-non-ascii, qmap-with-pointer-key, qproperty-without-notify, qstring-arg, qstring-insensitive-allocation, qstring-left, qstring-ref, qt-macros, qvariant-template-instantiation, range-loop, returning-data-from-temporary, rule-of-two-soft, skipped-base-method, strict-iterators, temporary-iterator, unused-non-trivial-variable, virtual-signal, writing-to-temporary, wrong-qglobalstatic +Requested checks: auto-unexpected-qstringbuilder, child-event-qobject-cast, connect-3arg-lambda, connect-by-name, connect-non-signal, connect-not-normalized, const-signal-or-slot, container-anti-pattern, detaching-temporary, foreach, fully-qualified-moc-types, incorrect-emit, inefficient-qlist-soft, install-event-filter, lambda-in-connect, lambda-unique-connection, mutable-container-key, non-pod-global-static, overridden-signal, post-event, qcolor-from-literal, qdatetime-utc, qdeleteall, qenums, qfileinfo-exists, qgetenv, qhash-namespace, qlatin1string-non-ascii, qmap-with-pointer-key, qproperty-without-notify, qstring-arg, qstring-insensitive-allocation, qstring-left, qstring-ref, qt-macros, qvariant-template-instantiation, range-loop, returning-data-from-temporary, rule-of-two-soft, skipped-base-method, strict-iterators, temporary-iterator, unused-non-trivial-variable, virtual-signal, writing-to-temporary, wrong-qevent-cast, wrong-qglobalstatic Invalid check: foo -Requested checks: auto-unexpected-qstringbuilder, child-event-qobject-cast, connect-3arg-lambda, connect-by-name, connect-non-signal, connect-not-normalized, const-signal-or-slot, container-anti-pattern, detaching-temporary, foreach, fully-qualified-moc-types, incorrect-emit, inefficient-qlist-soft, install-event-filter, lambda-in-connect, lambda-unique-connection, mutable-container-key, non-pod-global-static, overridden-signal, post-event, qcolor-from-literal, qdatetime-utc, qdeleteall, qenums, qfileinfo-exists, qgetenv, qhash-namespace, qlatin1string-non-ascii, qmap-with-pointer-key, qproperty-without-notify, qstring-arg, qstring-insensitive-allocation, qstring-left, qstring-ref, qt-macros, qvariant-template-instantiation, range-loop, returning-data-from-temporary, rule-of-two-soft, skipped-base-method, strict-iterators, temporary-iterator, unused-non-trivial-variable, virtual-signal, writing-to-temporary, wrong-qglobalstatic +Requested checks: auto-unexpected-qstringbuilder, child-event-qobject-cast, connect-3arg-lambda, connect-by-name, connect-non-signal, connect-not-normalized, const-signal-or-slot, container-anti-pattern, detaching-temporary, foreach, fully-qualified-moc-types, incorrect-emit, inefficient-qlist-soft, install-event-filter, lambda-in-connect, lambda-unique-connection, mutable-container-key, non-pod-global-static, overridden-signal, post-event, qcolor-from-literal, qdatetime-utc, qdeleteall, qenums, qfileinfo-exists, qgetenv, qhash-namespace, qlatin1string-non-ascii, qmap-with-pointer-key, qproperty-without-notify, qstring-arg, qstring-insensitive-allocation, qstring-left, qstring-ref, qt-macros, qvariant-template-instantiation, range-loop, returning-data-from-temporary, rule-of-two-soft, skipped-base-method, strict-iterators, temporary-iterator, unused-non-trivial-variable, virtual-signal, writing-to-temporary, wrong-qevent-cast, wrong-qglobalstatic Requested checks: foreach Requested checks: foreach, writing-to-temporary Invalid check: foo @@ -8,20 +8,20 @@ Requested checks: foreach, writing-to-temporary Requested checks: old-style-connect Requested checks: old-style-connect Requested checks: foreach, old-style-connect -Requested checks: auto-unexpected-qstringbuilder, base-class-event, child-event-qobject-cast, connect-3arg-lambda, connect-by-name, connect-non-signal, connect-not-normalized, const-signal-or-slot, container-anti-pattern, copyable-polymorphic, ctor-missing-parent-argument, detaching-temporary, foreach, fully-qualified-moc-types, function-args-by-ref, function-args-by-value, global-const-char-pointer, implicit-casts, incorrect-emit, inefficient-qlist-soft, install-event-filter, lambda-in-connect, lambda-unique-connection, missing-qobject-macro, missing-typeinfo, mutable-container-key, non-pod-global-static, old-style-connect, overridden-signal, post-event, qcolor-from-literal, qdatetime-utc, qdeleteall, qenums, qfileinfo-exists, qgetenv, qhash-namespace, qlatin1string-non-ascii, qmap-with-pointer-key, qproperty-without-notify, qstring-allocations, qstring-arg, qstring-insensitive-allocation, qstring-left, qstring-ref, qt-macros, qvariant-template-instantiation, range-loop, returning-data-from-temporary, returning-void-expression, rule-of-three, rule-of-two-soft, skipped-base-method, strict-iterators, temporary-iterator, unused-non-trivial-variable, virtual-call-ctor, virtual-signal, writing-to-temporary, wrong-qglobalstatic +Requested checks: auto-unexpected-qstringbuilder, base-class-event, child-event-qobject-cast, connect-3arg-lambda, connect-by-name, connect-non-signal, connect-not-normalized, const-signal-or-slot, container-anti-pattern, copyable-polymorphic, ctor-missing-parent-argument, detaching-temporary, foreach, fully-qualified-moc-types, function-args-by-ref, function-args-by-value, global-const-char-pointer, implicit-casts, incorrect-emit, inefficient-qlist-soft, install-event-filter, lambda-in-connect, lambda-unique-connection, missing-qobject-macro, missing-typeinfo, mutable-container-key, non-pod-global-static, old-style-connect, overridden-signal, post-event, qcolor-from-literal, qdatetime-utc, qdeleteall, qenums, qfileinfo-exists, qgetenv, qhash-namespace, qlatin1string-non-ascii, qmap-with-pointer-key, qproperty-without-notify, qstring-allocations, qstring-arg, qstring-insensitive-allocation, qstring-left, qstring-ref, qt-macros, qvariant-template-instantiation, range-loop, returning-data-from-temporary, returning-void-expression, rule-of-three, rule-of-two-soft, skipped-base-method, strict-iterators, temporary-iterator, unused-non-trivial-variable, virtual-call-ctor, virtual-signal, writing-to-temporary, wrong-qevent-cast, wrong-qglobalstatic Requested checks: implicit-casts Requested checks: foreach, implicit-casts Requested checks: old-style-connect -Requested checks: connect-by-name, connect-non-signal, connect-not-normalized, container-anti-pattern, fully-qualified-moc-types, lambda-in-connect, lambda-unique-connection, mutable-container-key, qcolor-from-literal, qdatetime-utc, qenums, qfileinfo-exists, qgetenv, qmap-with-pointer-key, qstring-arg, qstring-insensitive-allocation, qstring-ref, qt-macros, qvariant-template-instantiation, strict-iterators, temporary-iterator, unused-non-trivial-variable, writing-to-temporary, wrong-qglobalstatic -Requested checks: auto-unexpected-qstringbuilder, child-event-qobject-cast, connect-3arg-lambda, connect-by-name, connect-non-signal, connect-not-normalized, const-signal-or-slot, container-anti-pattern, detaching-temporary, foreach, fully-qualified-moc-types, incorrect-emit, inefficient-qlist-soft, install-event-filter, lambda-in-connect, lambda-unique-connection, mutable-container-key, non-pod-global-static, overridden-signal, post-event, qcolor-from-literal, qdatetime-utc, qdeleteall, qenums, qfileinfo-exists, qgetenv, qhash-namespace, qlatin1string-non-ascii, qmap-with-pointer-key, qproperty-without-notify, qstring-arg, qstring-insensitive-allocation, qstring-left, qstring-ref, qt-macros, qvariant-template-instantiation, range-loop, returning-data-from-temporary, rule-of-two-soft, skipped-base-method, strict-iterators, temporary-iterator, unused-non-trivial-variable, virtual-signal, writing-to-temporary, wrong-qglobalstatic -Requested checks: connect-by-name, connect-non-signal, connect-not-normalized, container-anti-pattern, fully-qualified-moc-types, lambda-in-connect, lambda-unique-connection, mutable-container-key, qcolor-from-literal, qdatetime-utc, qenums, qfileinfo-exists, qgetenv, qmap-with-pointer-key, qstring-arg, qstring-insensitive-allocation, qstring-ref, qt-macros, qvariant-template-instantiation, reserve-candidates, strict-iterators, temporary-iterator, unused-non-trivial-variable, writing-to-temporary, wrong-qglobalstatic -Requested checks: connect-by-name, connect-non-signal, connect-not-normalized, container-anti-pattern, fully-qualified-moc-types, lambda-in-connect, lambda-unique-connection, mutable-container-key, qcolor-from-literal, qdatetime-utc, qenums, qfileinfo-exists, qgetenv, qmap-with-pointer-key, qstring-arg, qstring-insensitive-allocation, qstring-ref, qt-macros, qvariant-template-instantiation, strict-iterators, temporary-iterator, unused-non-trivial-variable, writing-to-temporary, wrong-qglobalstatic -Requested checks: connect-by-name, connect-non-signal, connect-not-normalized, container-anti-pattern, foreach, fully-qualified-moc-types, implicit-casts, lambda-in-connect, lambda-unique-connection, mutable-container-key, qcolor-from-literal, qdatetime-utc, qenums, qfileinfo-exists, qgetenv, qmap-with-pointer-key, qstring-arg, qstring-insensitive-allocation, qstring-ref, qt-macros, qvariant-template-instantiation, strict-iterators, temporary-iterator, unused-non-trivial-variable, writing-to-temporary, wrong-qglobalstatic -Requested checks: auto-unexpected-qstringbuilder, child-event-qobject-cast, connect-3arg-lambda, connect-by-name, connect-non-signal, connect-not-normalized, const-signal-or-slot, container-anti-pattern, detaching-temporary, foreach, fully-qualified-moc-types, incorrect-emit, inefficient-qlist-soft, install-event-filter, lambda-in-connect, lambda-unique-connection, mutable-container-key, non-pod-global-static, overridden-signal, post-event, qcolor-from-literal, qdatetime-utc, qdeleteall, qenums, qfileinfo-exists, qgetenv, qhash-namespace, qlatin1string-non-ascii, qmap-with-pointer-key, qproperty-without-notify, qstring-arg, qstring-insensitive-allocation, qstring-left, qstring-ref, qt-macros, qvariant-template-instantiation, range-loop, returning-data-from-temporary, rule-of-two-soft, skipped-base-method, strict-iterators, temporary-iterator, unused-non-trivial-variable, virtual-signal, writing-to-temporary, wrong-qglobalstatic +Requested checks: connect-by-name, connect-non-signal, connect-not-normalized, container-anti-pattern, fully-qualified-moc-types, lambda-in-connect, lambda-unique-connection, mutable-container-key, qcolor-from-literal, qdatetime-utc, qenums, qfileinfo-exists, qgetenv, qmap-with-pointer-key, qstring-arg, qstring-insensitive-allocation, qstring-ref, qt-macros, qvariant-template-instantiation, strict-iterators, temporary-iterator, unused-non-trivial-variable, writing-to-temporary, wrong-qevent-cast, wrong-qglobalstatic +Requested checks: auto-unexpected-qstringbuilder, child-event-qobject-cast, connect-3arg-lambda, connect-by-name, connect-non-signal, connect-not-normalized, const-signal-or-slot, container-anti-pattern, detaching-temporary, foreach, fully-qualified-moc-types, incorrect-emit, inefficient-qlist-soft, install-event-filter, lambda-in-connect, lambda-unique-connection, mutable-container-key, non-pod-global-static, overridden-signal, post-event, qcolor-from-literal, qdatetime-utc, qdeleteall, qenums, qfileinfo-exists, qgetenv, qhash-namespace, qlatin1string-non-ascii, qmap-with-pointer-key, qproperty-without-notify, qstring-arg, qstring-insensitive-allocation, qstring-left, qstring-ref, qt-macros, qvariant-template-instantiation, range-loop, returning-data-from-temporary, rule-of-two-soft, skipped-base-method, strict-iterators, temporary-iterator, unused-non-trivial-variable, virtual-signal, writing-to-temporary, wrong-qevent-cast, wrong-qglobalstatic +Requested checks: connect-by-name, connect-non-signal, connect-not-normalized, container-anti-pattern, fully-qualified-moc-types, lambda-in-connect, lambda-unique-connection, mutable-container-key, qcolor-from-literal, qdatetime-utc, qenums, qfileinfo-exists, qgetenv, qmap-with-pointer-key, qstring-arg, qstring-insensitive-allocation, qstring-ref, qt-macros, qvariant-template-instantiation, reserve-candidates, strict-iterators, temporary-iterator, unused-non-trivial-variable, writing-to-temporary, wrong-qevent-cast, wrong-qglobalstatic +Requested checks: connect-by-name, connect-non-signal, connect-not-normalized, container-anti-pattern, fully-qualified-moc-types, lambda-in-connect, lambda-unique-connection, mutable-container-key, qcolor-from-literal, qdatetime-utc, qenums, qfileinfo-exists, qgetenv, qmap-with-pointer-key, qstring-arg, qstring-insensitive-allocation, qstring-ref, qt-macros, qvariant-template-instantiation, strict-iterators, temporary-iterator, unused-non-trivial-variable, writing-to-temporary, wrong-qevent-cast, wrong-qglobalstatic +Requested checks: connect-by-name, connect-non-signal, connect-not-normalized, container-anti-pattern, foreach, fully-qualified-moc-types, implicit-casts, lambda-in-connect, lambda-unique-connection, mutable-container-key, qcolor-from-literal, qdatetime-utc, qenums, qfileinfo-exists, qgetenv, qmap-with-pointer-key, qstring-arg, qstring-insensitive-allocation, qstring-ref, qt-macros, qvariant-template-instantiation, strict-iterators, temporary-iterator, unused-non-trivial-variable, writing-to-temporary, wrong-qevent-cast, wrong-qglobalstatic +Requested checks: auto-unexpected-qstringbuilder, child-event-qobject-cast, connect-3arg-lambda, connect-by-name, connect-non-signal, connect-not-normalized, const-signal-or-slot, container-anti-pattern, detaching-temporary, foreach, fully-qualified-moc-types, incorrect-emit, inefficient-qlist-soft, install-event-filter, lambda-in-connect, lambda-unique-connection, mutable-container-key, non-pod-global-static, overridden-signal, post-event, qcolor-from-literal, qdatetime-utc, qdeleteall, qenums, qfileinfo-exists, qgetenv, qhash-namespace, qlatin1string-non-ascii, qmap-with-pointer-key, qproperty-without-notify, qstring-arg, qstring-insensitive-allocation, qstring-left, qstring-ref, qt-macros, qvariant-template-instantiation, range-loop, returning-data-from-temporary, rule-of-two-soft, skipped-base-method, strict-iterators, temporary-iterator, unused-non-trivial-variable, virtual-signal, writing-to-temporary, wrong-qevent-cast, wrong-qglobalstatic Test9 -Requested checks: auto-unexpected-qstringbuilder, child-event-qobject-cast, connect-3arg-lambda, connect-by-name, connect-non-signal, connect-not-normalized, const-signal-or-slot, container-anti-pattern, detaching-temporary, foreach, fully-qualified-moc-types, incorrect-emit, inefficient-qlist-soft, install-event-filter, lambda-in-connect, lambda-unique-connection, mutable-container-key, non-pod-global-static, overridden-signal, post-event, qcolor-from-literal, qdatetime-utc, qdeleteall, qenums, qfileinfo-exists, qgetenv, qhash-namespace, qlatin1string-non-ascii, qmap-with-pointer-key, qproperty-without-notify, qstring-arg, qstring-insensitive-allocation, qstring-left, qstring-ref, qt-macros, qvariant-template-instantiation, range-loop, returning-data-from-temporary, rule-of-two-soft, skipped-base-method, strict-iterators, temporary-iterator, unused-non-trivial-variable, virtual-signal, writing-to-temporary, wrong-qglobalstatic -Requested checks: connect-by-name, connect-non-signal, connect-not-normalized, container-anti-pattern, fully-qualified-moc-types, lambda-in-connect, lambda-unique-connection, mutable-container-key, qcolor-from-literal, qdatetime-utc, qenums, qfileinfo-exists, qgetenv, qmap-with-pointer-key, qstring-arg, qstring-insensitive-allocation, qstring-ref, qt-macros, qvariant-template-instantiation, reserve-candidates, strict-iterators, temporary-iterator, unused-non-trivial-variable, writing-to-temporary, wrong-qglobalstatic -Requested checks: connect-by-name, connect-non-signal, connect-not-normalized, container-anti-pattern, fully-qualified-moc-types, implicit-casts, lambda-in-connect, lambda-unique-connection, mutable-container-key, qcolor-from-literal, qdatetime-utc, qenums, qfileinfo-exists, qgetenv, qmap-with-pointer-key, qstring-arg, qstring-insensitive-allocation, qstring-ref, qt-macros, qvariant-template-instantiation, reserve-candidates, strict-iterators, temporary-iterator, unused-non-trivial-variable, writing-to-temporary, wrong-qglobalstatic +Requested checks: auto-unexpected-qstringbuilder, child-event-qobject-cast, connect-3arg-lambda, connect-by-name, connect-non-signal, connect-not-normalized, const-signal-or-slot, container-anti-pattern, detaching-temporary, foreach, fully-qualified-moc-types, incorrect-emit, inefficient-qlist-soft, install-event-filter, lambda-in-connect, lambda-unique-connection, mutable-container-key, non-pod-global-static, overridden-signal, post-event, qcolor-from-literal, qdatetime-utc, qdeleteall, qenums, qfileinfo-exists, qgetenv, qhash-namespace, qlatin1string-non-ascii, qmap-with-pointer-key, qproperty-without-notify, qstring-arg, qstring-insensitive-allocation, qstring-left, qstring-ref, qt-macros, qvariant-template-instantiation, range-loop, returning-data-from-temporary, rule-of-two-soft, skipped-base-method, strict-iterators, temporary-iterator, unused-non-trivial-variable, virtual-signal, writing-to-temporary, wrong-qevent-cast, wrong-qglobalstatic +Requested checks: connect-by-name, connect-non-signal, connect-not-normalized, container-anti-pattern, fully-qualified-moc-types, lambda-in-connect, lambda-unique-connection, mutable-container-key, qcolor-from-literal, qdatetime-utc, qenums, qfileinfo-exists, qgetenv, qmap-with-pointer-key, qstring-arg, qstring-insensitive-allocation, qstring-ref, qt-macros, qvariant-template-instantiation, reserve-candidates, strict-iterators, temporary-iterator, unused-non-trivial-variable, writing-to-temporary, wrong-qevent-cast, wrong-qglobalstatic +Requested checks: connect-by-name, connect-non-signal, connect-not-normalized, container-anti-pattern, fully-qualified-moc-types, implicit-casts, lambda-in-connect, lambda-unique-connection, mutable-container-key, qcolor-from-literal, qdatetime-utc, qenums, qfileinfo-exists, qgetenv, qmap-with-pointer-key, qstring-arg, qstring-insensitive-allocation, qstring-ref, qt-macros, qvariant-template-instantiation, reserve-candidates, strict-iterators, temporary-iterator, unused-non-trivial-variable, writing-to-temporary, wrong-qevent-cast, wrong-qglobalstatic Requested checks: implicit-casts Requested checks: implicit-casts Could not find checks in comma separated string implicit-casts,no-implicit-casts @@ -51,6 +51,7 @@ Available checks and FixIts: - temporary-iterator - unused-non-trivial-variable - writing-to-temporary + - wrong-qevent-cast - wrong-qglobalstatic - Checks from level1: @@ -115,9 +116,9 @@ To enable FixIts for a check, also set the env variable CLAZY_FIXIT, for example FixIts are experimental and rewrite your code therefore only one FixIt is allowed per build. Specifying a list of different FixIts is not supported. Backup your code before running them. -Requested checks: connect-by-name, connect-non-signal, connect-not-normalized, container-anti-pattern, fully-qualified-moc-types, lambda-in-connect, lambda-unique-connection, mutable-container-key, qcolor-from-literal, qdatetime-utc, qfileinfo-exists, qmap-with-pointer-key, qstring-arg, qstring-insensitive-allocation, qstring-ref, qt-macros, qvariant-template-instantiation, strict-iterators, temporary-iterator, unused-non-trivial-variable, writing-to-temporary, wrong-qglobalstatic +Requested checks: connect-by-name, connect-non-signal, connect-not-normalized, container-anti-pattern, fully-qualified-moc-types, lambda-in-connect, lambda-unique-connection, mutable-container-key, qcolor-from-literal, qdatetime-utc, qfileinfo-exists, qmap-with-pointer-key, qstring-arg, qstring-insensitive-allocation, qstring-ref, qt-macros, qvariant-template-instantiation, strict-iterators, temporary-iterator, unused-non-trivial-variable, writing-to-temporary, wrong-qevent-cast, wrong-qglobalstatic Requested checks: implicit-casts Requested checks: implicit-casts -Requested checks: auto-unexpected-qstringbuilder, child-event-qobject-cast, connect-3arg-lambda, connect-by-name, connect-non-signal, connect-not-normalized, const-signal-or-slot, container-anti-pattern, detaching-temporary, foreach, fully-qualified-moc-types, incorrect-emit, inefficient-qlist-soft, install-event-filter, lambda-in-connect, lambda-unique-connection, mutable-container-key, non-pod-global-static, overridden-signal, post-event, qcolor-from-literal, qdatetime-utc, qdeleteall, qenums, qfileinfo-exists, qgetenv, qhash-namespace, qlatin1string-non-ascii, qmap-with-pointer-key, qproperty-without-notify, qstring-arg, qstring-insensitive-allocation, qstring-left, qstring-ref, qt-macros, qvariant-template-instantiation, range-loop, returning-data-from-temporary, rule-of-two-soft, skipped-base-method, strict-iterators, temporary-iterator, unused-non-trivial-variable, virtual-signal, writing-to-temporary, wrong-qglobalstatic -Requested checks: connect-by-name, connect-non-signal, connect-not-normalized, container-anti-pattern, fully-qualified-moc-types, lambda-in-connect, lambda-unique-connection, mutable-container-key, qcolor-from-literal, qdatetime-utc, qfileinfo-exists, qmap-with-pointer-key, qstring-arg, qstring-insensitive-allocation, qstring-ref, qt-macros, qvariant-template-instantiation, strict-iterators, temporary-iterator, unused-non-trivial-variable, writing-to-temporary, wrong-qglobalstatic -Requested checks: auto-unexpected-qstringbuilder, child-event-qobject-cast, connect-3arg-lambda, connect-by-name, connect-non-signal, connect-not-normalized, const-signal-or-slot, container-anti-pattern, detaching-temporary, foreach, fully-qualified-moc-types, incorrect-emit, inefficient-qlist-soft, install-event-filter, lambda-in-connect, lambda-unique-connection, mutable-container-key, non-pod-global-static, overridden-signal, post-event, qcolor-from-literal, qdatetime-utc, qdeleteall, qfileinfo-exists, qgetenv, qhash-namespace, qlatin1string-non-ascii, qmap-with-pointer-key, qproperty-without-notify, qstring-arg, qstring-insensitive-allocation, qstring-left, qstring-ref, qt-macros, qvariant-template-instantiation, range-loop, returning-data-from-temporary, rule-of-two-soft, skipped-base-method, strict-iterators, temporary-iterator, unused-non-trivial-variable, virtual-signal, writing-to-temporary, wrong-qglobalstatic +Requested checks: auto-unexpected-qstringbuilder, child-event-qobject-cast, connect-3arg-lambda, connect-by-name, connect-non-signal, connect-not-normalized, const-signal-or-slot, container-anti-pattern, detaching-temporary, foreach, fully-qualified-moc-types, incorrect-emit, inefficient-qlist-soft, install-event-filter, lambda-in-connect, lambda-unique-connection, mutable-container-key, non-pod-global-static, overridden-signal, post-event, qcolor-from-literal, qdatetime-utc, qdeleteall, qenums, qfileinfo-exists, qgetenv, qhash-namespace, qlatin1string-non-ascii, qmap-with-pointer-key, qproperty-without-notify, qstring-arg, qstring-insensitive-allocation, qstring-left, qstring-ref, qt-macros, qvariant-template-instantiation, range-loop, returning-data-from-temporary, rule-of-two-soft, skipped-base-method, strict-iterators, temporary-iterator, unused-non-trivial-variable, virtual-signal, writing-to-temporary, wrong-qevent-cast, wrong-qglobalstatic +Requested checks: connect-by-name, connect-non-signal, connect-not-normalized, container-anti-pattern, fully-qualified-moc-types, lambda-in-connect, lambda-unique-connection, mutable-container-key, qcolor-from-literal, qdatetime-utc, qfileinfo-exists, qmap-with-pointer-key, qstring-arg, qstring-insensitive-allocation, qstring-ref, qt-macros, qvariant-template-instantiation, strict-iterators, temporary-iterator, unused-non-trivial-variable, writing-to-temporary, wrong-qevent-cast, wrong-qglobalstatic +Requested checks: auto-unexpected-qstringbuilder, child-event-qobject-cast, connect-3arg-lambda, connect-by-name, connect-non-signal, connect-not-normalized, const-signal-or-slot, container-anti-pattern, detaching-temporary, foreach, fully-qualified-moc-types, incorrect-emit, inefficient-qlist-soft, install-event-filter, lambda-in-connect, lambda-unique-connection, mutable-container-key, non-pod-global-static, overridden-signal, post-event, qcolor-from-literal, qdatetime-utc, qdeleteall, qfileinfo-exists, qgetenv, qhash-namespace, qlatin1string-non-ascii, qmap-with-pointer-key, qproperty-without-notify, qstring-arg, qstring-insensitive-allocation, qstring-left, qstring-ref, qt-macros, qvariant-template-instantiation, range-loop, returning-data-from-temporary, rule-of-two-soft, skipped-base-method, strict-iterators, temporary-iterator, unused-non-trivial-variable, virtual-signal, writing-to-temporary, wrong-qevent-cast, wrong-qglobalstatic diff --git a/tests/wrong-qevent-cast/config.json b/tests/wrong-qevent-cast/config.json new file mode 100644 index 00000000..e7e6e0cb --- /dev/null +++ b/tests/wrong-qevent-cast/config.json @@ -0,0 +1,7 @@ +{ + "tests" : [ + { + "filename" : "main.cpp" + } + ] +} diff --git a/tests/wrong-qevent-cast/main.cpp b/tests/wrong-qevent-cast/main.cpp new file mode 100644 index 00000000..a212c6cd --- /dev/null +++ b/tests/wrong-qevent-cast/main.cpp @@ -0,0 +1,41 @@ +#include <QtCore/QObject> +#include <QtCore/QString> +#include <QtCore/QEvent> +#include <QtGui/QKeyEvent> + +void test(QEvent *ev) +{ + + switch (ev->type()) { + case QEvent::MouseMove: { + auto a = static_cast<QKeyEvent*>(ev); // Warn + auto b = static_cast<QMouseEvent*>(ev); // OK + break; + } + case QEvent::KeyPress: { + auto a = static_cast<QKeyEvent*>(ev); // OK + auto b = static_cast<QMouseEvent*>(ev); // Warn + + int val = 0; + switch (val) { // unrelated switch + case 1000: { + auto a = static_cast<QKeyEvent*>(ev); // OK + auto b = static_cast<QMouseEvent*>(ev); // Warn + } + } + break; + } + + case QEvent::Paint: + case QEvent::MetaCall: { + if (ev->type() == QEvent::Paint) + auto pe = static_cast<QPaintEvent*>(ev); // OK + break; + } + + default: + break; + } + + +} diff --git a/tests/wrong-qevent-cast/main.cpp.expected b/tests/wrong-qevent-cast/main.cpp.expected new file mode 100644 index 00000000..aaf8e0a0 --- /dev/null +++ b/tests/wrong-qevent-cast/main.cpp.expected @@ -0,0 +1,3 @@ +wrong-qevent-cast/main.cpp:11:22: warning: Cast from a QEvent::MouseMove event to QKeyEvent looks suspicious. [-Wclazy-wrong-qevent-cast] +wrong-qevent-cast/main.cpp:17:22: warning: Cast from a QEvent::KeyPress event to QMouseEvent looks suspicious. [-Wclazy-wrong-qevent-cast] +wrong-qevent-cast/main.cpp:23:30: warning: Cast from a QEvent::KeyPress event to QMouseEvent looks suspicious. [-Wclazy-wrong-qevent-cast] |