void NonPodGlobalStatic::VisitStmt()

in src/checks/level1/non-pod-global-static.cpp [43:102]


void NonPodGlobalStatic::VisitStmt(clang::Stmt *stm)
{
    VarDecl *varDecl = m_context->lastDecl ? dyn_cast<VarDecl>(m_context->lastDecl) : nullptr;
    if (!varDecl || varDecl->isConstexpr() || varDecl->isExternallyVisible() || !varDecl->isFileVarDecl()) {
        return;
    }

    if (shouldIgnoreFile(stm->getBeginLoc())) {
        return;
    }

    StorageDuration sd = varDecl->getStorageDuration();
    if (sd != StorageDuration::SD_Static) {
        return;
    }

    const SourceLocation declStart = varDecl->getBeginLoc();

    if (declStart.isMacroID()) {
        auto macroName = static_cast<std::string>(Lexer::getImmediateMacroName(declStart, sm(), lo()));
        if (clazy::startsWithAny(macroName, {"Q_IMPORT_PLUGIN", "Q_CONSTRUCTOR_FUNCTION", "Q_DESTRUCTOR_FUNCTION"})) { // Don't warn on these
            return;
        }
    }

    auto *ctorExpr = dyn_cast<CXXConstructExpr>(stm);
    if (!ctorExpr) {
        return;
    }

    auto *ctorDecl = ctorExpr->getConstructor();
    auto *recordDecl = ctorDecl ? ctorDecl->getParent() : nullptr;
    if (!recordDecl) {
        return;
    }

    if (recordDecl->hasTrivialDestructor()) {
        // Has a trivial dtor, but now lets check the ctors.

        if (ctorDecl->isDefaultConstructor() && recordDecl->hasTrivialDefaultConstructor()) {
            // both dtor and called ctor are trivial, no warning
            return;
        }
        if (ctorDecl->isConstexpr()) {
            // Used ctor is constexpr, it's fine
            return;
        }
    }

    if (m_context->isQtDeveloper() && clazy::isBootstrapping(m_context->ci.getPreprocessorOpts())) {
        return;
    }

    StringRef className = clazy::name(recordDecl);
    if (!shouldIgnoreType(className)) {
        const std::string varName = varDecl->getQualifiedNameAsString();
        const std::string error = std::string("non-POD static (") + className.data() + " " + varName + std::string(")");
        emitWarning(declStart, error);
    }
}