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);
}
}