From ebf99de982239da1aa1ce425ef2b233162a32bb8 Mon Sep 17 00:00:00 2001 From: Alexander Lohnau Date: Mon, 4 Mar 2024 17:11:07 +0100 Subject: [PATCH] Fix false positives when using a typedef in combination with a generic We should not use the underlying CXX record, because that will resolve the typedef We usually don't do this in our code, but QVector is one example where it has happened (in qt6) --- src/checks/level0/fully-qualified-moc-types.cpp | 6 ++++++ tests/fully-qualified-moc-types/main.cpp | 3 ++- tests/fully-qualified-moc-types/main.cpp.fixed.expected | 3 ++- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/checks/level0/fully-qualified-moc-types.cpp b/src/checks/level0/fully-qualified-moc-types.cpp index 19c3cf65..0d9ff14a 100644 --- a/src/checks/level0/fully-qualified-moc-types.cpp +++ b/src/checks/level0/fully-qualified-moc-types.cpp @@ -107,6 +107,12 @@ static std::string getQualifiedNameOfType(const Type *ptr, const LangOptions &lo } if (auto *typedefDecl = ptr->getAs(); typedefDecl && typedefDecl->getDecl()) { return typedefDecl->getDecl()->getQualifiedNameAsString(); + } else if (auto templateSpec = ptr->getAs()) { + // In case one uses a typedef with generics, like QVector in Qt6 + // The docs indicate getAsTemplateDecl might be null - so be prepared for that + if (auto *decl = templateSpec->getTemplateName().getAsTemplateDecl()) { + return decl->getQualifiedNameAsString(); + } } else if (auto recordDecl = ptr->getAsRecordDecl()) { return recordDecl->getQualifiedNameAsString(); } diff --git a/tests/fully-qualified-moc-types/main.cpp b/tests/fully-qualified-moc-types/main.cpp index 0e568fb8..cac88a53 100644 --- a/tests/fully-qualified-moc-types/main.cpp +++ b/tests/fully-qualified-moc-types/main.cpp @@ -61,7 +61,7 @@ namespace NS { } - +template using DummyListAlias = QList; namespace { // annonymous struct AnnonFoo {}; }; @@ -91,6 +91,7 @@ public Q_SLOTS: inline void nestedGeneric(QDBusPendingReply>) {} // OK inline void nestedNotFullyQualifiedGeneric(QDBusPendingReply>) {} // WARN inline const MyList& notQualWithModifier() {return lst;}; + DummyListAlias myList() { return {1,2,3};}; private: MyList lst; }; diff --git a/tests/fully-qualified-moc-types/main.cpp.fixed.expected b/tests/fully-qualified-moc-types/main.cpp.fixed.expected index 956110c2..eea8a46a 100644 --- a/tests/fully-qualified-moc-types/main.cpp.fixed.expected +++ b/tests/fully-qualified-moc-types/main.cpp.fixed.expected @@ -61,7 +61,7 @@ namespace NS { } - +template using DummyListAlias = QList; namespace { // annonymous struct AnnonFoo {}; }; @@ -91,6 +91,7 @@ public Q_SLOTS: inline void nestedGeneric(QDBusPendingReply>) {} // OK inline void nestedNotFullyQualifiedGeneric(QDBusPendingReply>) {} // WARN inline const MyObj2::MyList& notQualWithModifier() {return lst;}; + DummyListAlias myList() { return {1,2,3};}; private: MyList lst; };