From 90ed482496be0186e95c89e60035da555261de4e Mon Sep 17 00:00:00 2001 From: Stephan Bergmann Date: Tue, 31 Mar 2015 13:18:16 +0200 Subject: Reduce to static_cast any reinterpret_cast from void pointers Change-Id: I514e183571e4ac109f59c4bdfccdc553c36c26ee --- compilerplugins/clang/redundantcast.cxx | 54 +++++++++++++++++++++++++++++++-- 1 file changed, 51 insertions(+), 3 deletions(-) (limited to 'compilerplugins') 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, public loplugin::Plugin + public RecursiveASTVisitor, 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(); + 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 X("redundantcast"); +loplugin::Plugin::Registration X("redundantcast", true); } -- cgit v1.2.3