new loplugin:emptyif
Change-Id: I1092115a0ceb3a5e6680a4b724b129f98a892c42 Reviewed-on: https://gerrit.libreoffice.org/48128 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
This commit is contained in:
95
compilerplugins/clang/emptyif.cxx
Normal file
95
compilerplugins/clang/emptyif.cxx
Normal file
@@ -0,0 +1,95 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* This file is part of the LibreOffice project.
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#include <cassert>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <set>
|
||||
#include "plugin.hxx"
|
||||
|
||||
/**
|
||||
Check for places where we do
|
||||
if (xxx) ;
|
||||
or
|
||||
if (xxx) {}
|
||||
*/
|
||||
namespace
|
||||
{
|
||||
class EmptyIf : public RecursiveASTVisitor<EmptyIf>, public loplugin::RewritePlugin
|
||||
{
|
||||
public:
|
||||
explicit EmptyIf(loplugin::InstantiationData const& data)
|
||||
: RewritePlugin(data)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void run() override
|
||||
{
|
||||
StringRef fn(compiler.getSourceManager()
|
||||
.getFileEntryForID(compiler.getSourceManager().getMainFileID())
|
||||
->getName());
|
||||
TraverseDecl(compiler.getASTContext().getTranslationUnitDecl());
|
||||
}
|
||||
|
||||
bool VisitIfStmt(IfStmt const*);
|
||||
|
||||
private:
|
||||
bool ContainsComment(Stmt const*);
|
||||
};
|
||||
|
||||
static bool empty(Stmt const* stmt)
|
||||
{
|
||||
if (isa<NullStmt>(stmt))
|
||||
return true;
|
||||
auto compoundStmt = dyn_cast<CompoundStmt>(stmt);
|
||||
if (!compoundStmt)
|
||||
return false;
|
||||
return compoundStmt->size() == 0;
|
||||
}
|
||||
|
||||
bool EmptyIf::ContainsComment(Stmt const* stmt)
|
||||
{
|
||||
auto range = stmt->getSourceRange();
|
||||
SourceManager& SM = compiler.getSourceManager();
|
||||
SourceLocation startLoc = range.getBegin();
|
||||
SourceLocation endLoc = range.getEnd();
|
||||
char const* p1 = SM.getCharacterData(startLoc);
|
||||
char const* p2 = SM.getCharacterData(endLoc);
|
||||
p2 += Lexer::MeasureTokenLength(endLoc, SM, compiler.getLangOpts());
|
||||
auto s = llvm::StringRef(p1, p2 - p1);
|
||||
return s.find("//") != llvm::StringRef::npos || s.find("/*") != llvm::StringRef::npos
|
||||
|| s.find("#if") != llvm::StringRef::npos;
|
||||
}
|
||||
|
||||
bool EmptyIf::VisitIfStmt(IfStmt const* ifStmt)
|
||||
{
|
||||
if (ignoreLocation(ifStmt))
|
||||
return true;
|
||||
|
||||
if (ifStmt->getElse() && empty(ifStmt->getElse()) && !ContainsComment(ifStmt->getElse()))
|
||||
{
|
||||
report(DiagnosticsEngine::Warning, "empty else body", ifStmt->getElse()->getLocStart())
|
||||
<< ifStmt->getElse()->getSourceRange();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!ifStmt->getElse() && empty(ifStmt->getThen()) && !ContainsComment(ifStmt->getThen()))
|
||||
{
|
||||
report(DiagnosticsEngine::Warning, "empty if body", ifStmt->getLocStart())
|
||||
<< ifStmt->getSourceRange();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
loplugin::Plugin::Registration<EmptyIf> X("emptyif", true);
|
||||
}
|
||||
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
Reference in New Issue
Block a user