diff options
author | Stephan Bergmann <sbergman@redhat.com> | 2015-03-31 13:18:16 +0200 |
---|---|---|
committer | Stephan Bergmann <sbergman@redhat.com> | 2015-03-31 13:18:16 +0200 |
commit | 90ed482496be0186e95c89e60035da555261de4e (patch) | |
tree | 332c655ef15408a74ea03e6ce4b3ece61baa387b /compilerplugins | |
parent | 698a6d4ab6e2f8485ed4e1d8322ac74c7087d621 (diff) |
Reduce to static_cast any reinterpret_cast from void pointers
Change-Id: I514e183571e4ac109f59c4bdfccdc553c36c26ee
Diffstat (limited to 'compilerplugins')
-rw-r--r-- | compilerplugins/clang/redundantcast.cxx | 54 |
1 files changed, 51 insertions, 3 deletions
diff --git a/compilerplugins/clang/redundantcast.cxx b/compilerplugins/clang/redundantcast.cxx index 007a63873c9f..ee731e2938fc 100644 --- a/compilerplugins/clang/redundantcast.cxx +++ b/compilerplugins/clang/redundantcast.cxx @@ -36,10 +36,11 @@ bool isVoidPointer(QualType type) { } class RedundantCast: - public RecursiveASTVisitor<RedundantCast>, public loplugin::Plugin + public RecursiveASTVisitor<RedundantCast>, public loplugin::RewritePlugin { public: - explicit RedundantCast(InstantiationData const & data): Plugin(data) {} + explicit RedundantCast(InstantiationData const & data): RewritePlugin(data) + {} virtual void run() override { if (compiler.getLangOpts().CPlusPlus) { @@ -49,6 +50,8 @@ public: bool VisitImplicitCastExpr(ImplicitCastExpr const * expr); + bool VisitCXXReinterpretCastExpr(CXXReinterpretCastExpr const * expr); + bool VisitCallExpr(CallExpr const * expr); bool VisitCXXDeleteExpr(CXXDeleteExpr const * expr); @@ -159,6 +162,51 @@ bool RedundantCast::VisitImplicitCastExpr(const ImplicitCastExpr * expr) { return true; } +bool RedundantCast::VisitCXXReinterpretCastExpr( + CXXReinterpretCastExpr const * expr) +{ + if (ignoreLocation(expr) + || !expr->getSubExpr()->getType()->isVoidPointerType()) + { + return true; + } + auto t = expr->getType()->getAs<PointerType>(); + if (t == nullptr || !t->getPointeeType()->isObjectType()) { + return true; + } + if (rewriter != nullptr) { + auto loc = expr->getLocStart(); + while (compiler.getSourceManager().isMacroArgExpansion(loc)) { + loc = compiler.getSourceManager().getImmediateMacroCallerLoc(loc); + } + if (compat::isMacroBodyExpansion(compiler, loc)) { + auto loc2 = expr->getLocEnd(); + while (compiler.getSourceManager().isMacroArgExpansion(loc2)) { + loc2 = compiler.getSourceManager().getImmediateMacroCallerLoc( + loc2); + } + if (compat::isMacroBodyExpansion(compiler, loc2)) { + //TODO: check loc, loc2 are in same macro body expansion + loc = compiler.getSourceManager().getSpellingLoc(loc); + } + } + auto s = compiler.getSourceManager().getCharacterData(loc); + auto n = Lexer::MeasureTokenLength( + loc, compiler.getSourceManager(), compiler.getLangOpts()); + std::string tok(s, n); + if (tok == "reinterpret_cast" && replaceText(loc, n, "static_cast")) { + return true; + } + } + report( + DiagnosticsEngine::Warning, + "reinterpret_cast from %0 to %1 can be simplified to static_cast", + expr->getExprLoc()) + << expr->getSubExprAsWritten()->getType() << expr->getType() + << expr->getSourceRange(); + return true; +} + bool RedundantCast::VisitCallExpr(CallExpr const * expr) { if (ignoreLocation(expr)) { return true; @@ -229,7 +277,7 @@ bool RedundantCast::visitBinOp(BinaryOperator const * expr) { return true; } -loplugin::Plugin::Registration<RedundantCast> X("redundantcast"); +loplugin::Plugin::Registration<RedundantCast> X("redundantcast", true); } |