diff options
author | Stephan Bergmann <sbergman@redhat.com> | 2016-01-06 16:47:09 +0100 |
---|---|---|
committer | Stephan Bergmann <sbergman@redhat.com> | 2016-01-06 16:48:15 +0100 |
commit | 6bffbf100e82da19067338e59adc6915dfc748d5 (patch) | |
tree | a7147876857ff6d161e56bbf9b3578e4174fbea4 /compilerplugins/clang/store/nullptr.cxx | |
parent | 593f3b703cd43807f67a01c33c851ca9723493a6 (diff) |
Enable loplugin:nullptr
I had it locally enabled for like a month now, and it did not produce any more
noise than any of the other plugins.
Change-Id: I94dab702c537969cf32922f6e88b4f5b503cd3f5
Diffstat (limited to 'compilerplugins/clang/store/nullptr.cxx')
-rw-r--r-- | compilerplugins/clang/store/nullptr.cxx | 323 |
1 files changed, 0 insertions, 323 deletions
diff --git a/compilerplugins/clang/store/nullptr.cxx b/compilerplugins/clang/store/nullptr.cxx deleted file mode 100644 index 6bf4e54d3f15..000000000000 --- a/compilerplugins/clang/store/nullptr.cxx +++ /dev/null @@ -1,323 +0,0 @@ -/* -*- 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 <set> - -#include "compat.hxx" -#include "plugin.hxx" - -namespace { - -char const * kindName(Expr::NullPointerConstantKind kind) { - switch (kind) { - case Expr::NPCK_NotNull: - assert(false); // cannot happen - // fall through - case Expr::NPCK_ZeroExpression: - return "ZeroExpression"; - case Expr::NPCK_ZeroLiteral: - return "ZeroLiteral"; - case Expr::NPCK_CXX11_nullptr: - return "CXX11_nullptr"; - case Expr::NPCK_GNUNull: - return "GNUNull"; - } -} - -class Nullptr: - public RecursiveASTVisitor<Nullptr>, public loplugin::RewritePlugin -{ -public: - explicit Nullptr(InstantiationData const & data): RewritePlugin(data) {} - - void run() override - { TraverseDecl(compiler.getASTContext().getTranslationUnitDecl()); } - - bool VisitImplicitCastExpr(CastExpr const * expr); - - bool VisitGNUNullExpr(GNUNullExpr const * expr); - - bool VisitBinaryOperator(BinaryOperator const * expr); - - bool VisitCXXOperatorCallExpr(CXXOperatorCallExpr const * expr); - - // bool shouldVisitTemplateInstantiations() const { return true; } - -private: - bool isInLokIncludeFile(SourceLocation spellingLocation) const; - - bool isFromCIncludeFile(SourceLocation spellingLocation) const; - - bool isMacroBodyExpansion(SourceLocation location) const; - - void handleNull( - Expr const * expr, char const * castKind, - Expr::NullPointerConstantKind nullPointerKind); - - void rewriteOrWarn( - Expr const * expr, char const * castKind, - Expr::NullPointerConstantKind nullPointerKind, - char const * replacement); - - std::set<Expr const *> gnuNulls_; -}; - -bool Nullptr::VisitImplicitCastExpr(CastExpr const * expr) { - if (ignoreLocation(expr)) { - return true; - } - switch (expr->getCastKind()) { - case CK_NullToPointer: - case CK_NullToMemberPointer: - break; - default: - return true; - } - Expr::NullPointerConstantKind k = expr->isNullPointerConstant( - compiler.getASTContext(), Expr::NPC_ValueDependentIsNotNull); - switch (k) { - case Expr::NPCK_NotNull: - k = expr->isNullPointerConstant( - compiler.getASTContext(), Expr::NPC_ValueDependentIsNull); - switch (k) { - case Expr::NPCK_NotNull: - break; - case Expr::NPCK_ZeroExpression: - case Expr::NPCK_ZeroLiteral: - report( - DiagnosticsEngine::Warning, - "suspicious ValueDependentIsNull %0", expr->getLocStart()) - << kindName(k) << expr->getSourceRange(); - break; - default: - assert(false); // cannot happen - } - break; - case Expr::NPCK_CXX11_nullptr: - break; - default: - handleNull(expr->getSubExpr(), expr->getCastKindName(), k); - break; - } - return true; -} - -bool Nullptr::VisitGNUNullExpr(GNUNullExpr const * expr) { - if (ignoreLocation(expr)) { - return true; - } - handleNull(expr, nullptr, Expr::NPCK_GNUNull); - return true; -} - -bool Nullptr::VisitBinaryOperator(BinaryOperator const * expr) { - if (ignoreLocation(expr)) { - return true; - } - Expr const * e; - switch (expr->getOpcode()) { - case BO_EQ: - case BO_NE: - if (expr->getRHS()->getType()->isPointerType()) { - e = expr->getLHS(); - break; - } - // fall through - case BO_Assign: - if (expr->getLHS()->getType()->isPointerType()) { - e = expr->getRHS(); - break; - } - // fall through - default: - return true; - } - //TODO: detect NPCK_ZeroExpression where appropriate - auto const lit = dyn_cast<IntegerLiteral>(e->IgnoreParenImpCasts()); - if (lit == nullptr || lit->getValue().getBoolValue()) { - return true; - } - handleNull(e, nullptr, Expr::NPCK_ZeroLiteral); - return true; -} - -bool Nullptr::VisitCXXOperatorCallExpr(CXXOperatorCallExpr const * expr) { - if (ignoreLocation(expr)) { - return true; - } - Expr const * e; - switch (expr->getOperator()) { - case OO_EqualEqual: - case OO_ExclaimEqual: - if (expr->getArg(1)->getType()->isPointerType()) { - e = expr->getArg(0); - break; - } - // fall through - case OO_Equal: - if (expr->getArg(0)->getType()->isPointerType()) { - e = expr->getArg(1); - break; - } - // fall through - default: - return true; - } - //TODO: detect NPCK_ZeroExpression where appropriate - auto const lit = dyn_cast<IntegerLiteral>(e->IgnoreParenImpCasts()); - if (lit == nullptr || lit->getValue().getBoolValue()) { - return true; - } - handleNull(e, nullptr, Expr::NPCK_ZeroLiteral); - return true; -} - -bool Nullptr::isInLokIncludeFile(SourceLocation spellingLocation) const { - return compiler.getSourceManager().getFilename(spellingLocation) - .startswith(SRCDIR "/include/LibreOfficeKit/"); -} - -bool Nullptr::isFromCIncludeFile(SourceLocation spellingLocation) const { - return !compat::isInMainFile(compiler.getSourceManager(), spellingLocation) - && (StringRef( - compiler.getSourceManager().getPresumedLoc(spellingLocation) - .getFilename()) - .endswith(".h")); -} - -bool Nullptr::isMacroBodyExpansion(SourceLocation location) const { -#if (__clang_major__ == 3 && __clang_minor__ >= 3) || __clang_major__ > 3 - return compiler.getSourceManager().isMacroBodyExpansion(location); -#else - return location.isMacroID() - && !compiler.getSourceManager().isMacroArgExpansion(location); -#endif -} - -void Nullptr::handleNull( - Expr const * expr, char const * castKind, - Expr::NullPointerConstantKind nullPointerKind) -{ - auto e = expr; - SourceLocation loc; - for (;;) { - e = e->IgnoreImpCasts(); - loc = e->getLocStart(); - while (compiler.getSourceManager().isMacroArgExpansion(loc)) { - loc = compiler.getSourceManager().getImmediateMacroCallerLoc(loc); - } - if (isMacroBodyExpansion(loc)) { - if (Lexer::getImmediateMacroName( - loc, compiler.getSourceManager(), compiler.getLangOpts()) - == "NULL") - { - if (!compiler.getLangOpts().CPlusPlus) { - //TODO: if !castKind, warn if NULL is passed into fn call - // ellipsis, cast to void* - return; - } - loc = compiler.getSourceManager() - .getImmediateExpansionRange(loc).first; - if (isInUnoIncludeFile( - compiler.getSourceManager().getSpellingLoc(loc)) - || isInLokIncludeFile( - compiler.getSourceManager().getSpellingLoc(loc)) - || isFromCIncludeFile( - compiler.getSourceManager().getSpellingLoc(loc))) - { - //TODO: if !castKind, warn if NULL is passed into fn call - // ellipsis, cast to void* - return; - } - } else if (ignoreLocation( - compiler.getSourceManager().getSpellingLoc(loc))) - { - return; - } - } - ParenExpr const * pe = dyn_cast<ParenExpr>(e); - if (pe == nullptr) { - break; - } - e = pe->getSubExpr(); - } - if (nullPointerKind == Expr::NPCK_GNUNull) { - if (castKind == nullptr) { - if (gnuNulls_.erase(expr) == 1) { - return; - } - } else { - auto const ok = gnuNulls_.insert(expr).second; - assert(ok); (void) ok; - } - } - auto const asMacro = !compiler.getLangOpts().CPlusPlus - || isInUnoIncludeFile(compiler.getSourceManager().getSpellingLoc(loc)) - || isInLokIncludeFile(compiler.getSourceManager().getSpellingLoc(loc)) - || isFromCIncludeFile(compiler.getSourceManager().getSpellingLoc(loc)); - assert(!asMacro || nullPointerKind != Expr::NPCK_GNUNull); - rewriteOrWarn(e, castKind, nullPointerKind, asMacro ? "NULL" : "nullptr"); -} - -void Nullptr::rewriteOrWarn( - Expr const * expr, char const * castKind, - Expr::NullPointerConstantKind nullPointerKind, char const * replacement) -{ - if (rewriter != nullptr) { - SourceLocation locStart(expr->getLocStart()); - while (compiler.getSourceManager().isMacroArgExpansion(locStart)) { - locStart = compiler.getSourceManager() - .getImmediateMacroCallerLoc(locStart); - } - if (compiler.getLangOpts().CPlusPlus && isMacroBodyExpansion(locStart) - && (Lexer::getImmediateMacroName( - locStart, compiler.getSourceManager(), - compiler.getLangOpts()) - == "NULL")) - { - locStart = compiler.getSourceManager().getImmediateExpansionRange( - locStart).first; - } - SourceLocation locEnd(expr->getLocEnd()); - while (compiler.getSourceManager().isMacroArgExpansion(locEnd)) { - locEnd = compiler.getSourceManager() - .getImmediateMacroCallerLoc(locEnd); - } - if (compiler.getLangOpts().CPlusPlus && isMacroBodyExpansion(locEnd) - && (Lexer::getImmediateMacroName( - locEnd, compiler.getSourceManager(), - compiler.getLangOpts()) - == "NULL")) - { - locEnd = compiler.getSourceManager().getImmediateExpansionRange( - locEnd).first; - } - if (replaceText(SourceRange(compiler.getSourceManager().getSpellingLoc(locStart), compiler.getSourceManager().getSpellingLoc(locEnd)), replacement)) { - return; - } - } - if (castKind == nullptr) { - report(DiagnosticsEngine::Warning, "%0 -> %1", expr->getLocStart()) - << kindName(nullPointerKind) << replacement - << expr->getSourceRange(); - } else { - report( - DiagnosticsEngine::Warning, "%0 ValueDependentIsNotNull %1 -> %2", - expr->getLocStart()) - << castKind << kindName(nullPointerKind) << replacement - << expr->getSourceRange(); - } -} - -loplugin::Plugin::Registration<Nullptr> X("nullptr", true); - -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |