diff options
Diffstat (limited to 'compilerplugins/clang/redundantfcast.cxx')
-rw-r--r-- | compilerplugins/clang/redundantfcast.cxx | 56 |
1 files changed, 39 insertions, 17 deletions
diff --git a/compilerplugins/clang/redundantfcast.cxx b/compilerplugins/clang/redundantfcast.cxx index a53c42d73add..8879a386d621 100644 --- a/compilerplugins/clang/redundantfcast.cxx +++ b/compilerplugins/clang/redundantfcast.cxx @@ -13,6 +13,7 @@ #include "plugin.hxx" #include <iostream> #include <fstream> +#include <unordered_set> namespace { @@ -53,9 +54,10 @@ public: { return true; } - report(DiagnosticsEngine::Warning, "redundant functional cast from %0 to %1", - cxxFunctionalCastExpr->getExprLoc()) - << t2 << t1 << cxxFunctionalCastExpr->getSourceRange(); + if (m_Seen.insert(cxxFunctionalCastExpr->getExprLoc()).second) + report(DiagnosticsEngine::Warning, "redundant functional cast from %0 to %1", + cxxFunctionalCastExpr->getExprLoc()) + << t2 << t1 << cxxFunctionalCastExpr->getSourceRange(); return true; } @@ -103,11 +105,14 @@ public: if (t1.getCanonicalType().getTypePtr() != paramClassOrStructType) continue; - report(DiagnosticsEngine::Warning, "redundant functional cast from %0 to %1", - arg->getExprLoc()) - << t2 << t1 << arg->getSourceRange(); - report(DiagnosticsEngine::Note, "in call to method here", param->getLocation()) - << param->getSourceRange(); + if (m_Seen.insert(arg->getExprLoc()).second) + { + report(DiagnosticsEngine::Warning, "redundant functional cast from %0 to %1", + arg->getExprLoc()) + << t2 << t1 << arg->getSourceRange(); + report(DiagnosticsEngine::Note, "in call to method here", param->getLocation()) + << param->getSourceRange(); + } } return true; } @@ -146,15 +151,28 @@ public: if (t1.getCanonicalType().getTypePtr() != paramClassOrStructType) continue; - report(DiagnosticsEngine::Warning, "redundant functional cast from %0 to %1", - arg->getExprLoc()) - << t2 << t1 << arg->getSourceRange(); - report(DiagnosticsEngine::Note, "in call to method here", param->getLocation()) - << param->getSourceRange(); + if (m_Seen.insert(arg->getExprLoc()).second) + { + report(DiagnosticsEngine::Warning, "redundant functional cast from %0 to %1", + arg->getExprLoc()) + << t2 << t1 << arg->getSourceRange(); + report(DiagnosticsEngine::Note, "in call to method here", param->getLocation()) + << param->getSourceRange(); + } } return true; } + // Find redundant cast to std::function, where clang reports + // two different types for the inner and outer + static bool isRedundantStdFunctionCast(CXXFunctionalCastExpr const* expr) + { + auto cxxConstruct = dyn_cast<CXXConstructExpr>(compat::IgnoreImplicit(expr->getSubExpr())); + if (!cxxConstruct) + return false; + return isa<LambdaExpr>(cxxConstruct->getArg(0)); + } + bool VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr const* expr) { if (ignoreLocation(expr)) @@ -166,7 +184,8 @@ public: return true; auto const t1 = expr->getTypeAsWritten(); auto const t2 = compat::getSubExprAsWritten(expr)->getType(); - if (t1.getCanonicalType().getTypePtr() != t2.getCanonicalType().getTypePtr()) + if (!(t1.getCanonicalType().getTypePtr() == t2.getCanonicalType().getTypePtr() + || isRedundantStdFunctionCast(expr))) { return true; } @@ -191,9 +210,10 @@ public: if (tc.Typedef("sal_Int32").GlobalNamespace()) return true; - report(DiagnosticsEngine::Warning, "redundant functional cast from %0 to %1", - expr->getExprLoc()) - << t2 << t1 << expr->getSourceRange(); + if (m_Seen.insert(expr->getExprLoc()).second) + report(DiagnosticsEngine::Warning, "redundant functional cast from %0 to %1", + expr->getExprLoc()) + << t2 << t1 << expr->getSourceRange(); //getParentStmt(expr)->dump(); return true; } @@ -218,6 +238,8 @@ public: if (preRun()) TraverseDecl(compiler.getASTContext().getTranslationUnitDecl()); } + + std::unordered_set<SourceLocation> m_Seen; }; static loplugin::Plugin::Registration<RedundantFCast> redundantfcast("redundantfcast"); |