diff options
author | Noel <noel.grandin@collabora.co.uk> | 2021-03-05 08:37:41 +0200 |
---|---|---|
committer | Noel Grandin <noel.grandin@collabora.co.uk> | 2021-03-06 13:08:26 +0100 |
commit | bd37588605f7773d41b5388b18952e5c90f12214 (patch) | |
tree | 498116ae9376e7671bf0441e476dad16f2bd197e /compilerplugins/clang/staticdynamic.cxx | |
parent | 4474d167e1b69ab9ca8a97c636f0400a5084641a (diff) |
loplugin:staticdynamic look for static after dynamic
Change-Id: Ic3066d9a9441e369370cc6aa0fbffb9a321bc928
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/111985
Tested-by: Jenkins
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
Diffstat (limited to 'compilerplugins/clang/staticdynamic.cxx')
-rw-r--r-- | compilerplugins/clang/staticdynamic.cxx | 64 |
1 files changed, 51 insertions, 13 deletions
diff --git a/compilerplugins/clang/staticdynamic.cxx b/compilerplugins/clang/staticdynamic.cxx index b2383413b287..b104b0333fcd 100644 --- a/compilerplugins/clang/staticdynamic.cxx +++ b/compilerplugins/clang/staticdynamic.cxx @@ -45,22 +45,26 @@ public: private: // the key is the pair of VarDecl and the type being cast to. - typedef std::map<std::pair<VarDecl const*, clang::Type const*>, SourceLocation> MapType; - MapType staticCastVars; + struct BlockState + { + std::map<std::pair<VarDecl const*, clang::Type const*>, SourceLocation> staticCastVars; + std::map<std::pair<VarDecl const*, clang::Type const*>, SourceLocation> dynamicCastVars; + }; // only maintain state inside a single basic block, we're not trying to analyse // cross-block interactions. - std::vector<MapType> blockStack; + std::vector<BlockState> blockStack; + BlockState blockState; }; bool StaticDynamic::PreTraverseCompoundStmt(CompoundStmt*) { - blockStack.push_back(std::move(staticCastVars)); + blockStack.push_back(std::move(blockState)); return true; } bool StaticDynamic::PostTraverseCompoundStmt(CompoundStmt*, bool) { - staticCastVars = std::move(blockStack.back()); + blockState = std::move(blockStack.back()); blockStack.pop_back(); return true; } @@ -86,8 +90,28 @@ bool StaticDynamic::VisitCXXStaticCastExpr(CXXStaticCastExpr const* staticCastEx auto varDecl = dyn_cast_or_null<VarDecl>(subExprDecl->getDecl()); if (!varDecl) return true; - staticCastVars.insert({ { varDecl, staticCastExpr->getTypeAsWritten().getTypePtr() }, - compat::getBeginLoc(staticCastExpr) }); + auto it = blockState.dynamicCastVars.find( + { varDecl, staticCastExpr->getTypeAsWritten().getTypePtr() }); + if (it != blockState.dynamicCastVars.end()) + { + StringRef fn = getFilenameOfLocation( + compiler.getSourceManager().getSpellingLoc(compat::getBeginLoc(staticCastExpr))); + // loop + if (loplugin::isSamePathname(fn, SRCDIR "/basctl/source/basicide/basobj3.cxx")) + return true; + if (loplugin::isSamePathname(fn, SRCDIR "/sw/source/core/doc/swserv.cxx")) + return true; + if (loplugin::isSamePathname(fn, SRCDIR "/sw/source/core/text/txtfly.cxx")) + return true; + + report(DiagnosticsEngine::Warning, "static_cast after dynamic_cast", + compat::getBeginLoc(staticCastExpr)) + << staticCastExpr->getSourceRange(); + report(DiagnosticsEngine::Note, "dynamic_cast here", it->second); + return true; + } + blockState.staticCastVars.insert({ { varDecl, staticCastExpr->getTypeAsWritten().getTypePtr() }, + compat::getBeginLoc(staticCastExpr) }); return true; } @@ -102,13 +126,27 @@ bool StaticDynamic::VisitCXXDynamicCastExpr(CXXDynamicCastExpr const* dynamicCas auto varDecl = dyn_cast_or_null<VarDecl>(subExprDecl->getDecl()); if (!varDecl) return true; - auto it = staticCastVars.find({ varDecl, dynamicCastExpr->getTypeAsWritten().getTypePtr() }); - if (it == staticCastVars.end()) + auto it = blockState.staticCastVars.find( + { varDecl, dynamicCastExpr->getTypeAsWritten().getTypePtr() }); + if (it != blockState.staticCastVars.end()) + { + report(DiagnosticsEngine::Warning, "dynamic_cast after static_cast", + compat::getBeginLoc(dynamicCastExpr)) + << dynamicCastExpr->getSourceRange(); + report(DiagnosticsEngine::Note, "static_cast here", it->second); return true; - report(DiagnosticsEngine::Warning, "dynamic_cast after static_cast", - compat::getBeginLoc(dynamicCastExpr)) - << dynamicCastExpr->getSourceRange(); - report(DiagnosticsEngine::Note, "static_cast here", it->second); + } + auto loc = compat::getBeginLoc(dynamicCastExpr); + if (compiler.getSourceManager().isMacroArgExpansion(loc) + && (Lexer::getImmediateMacroNameForDiagnostics(loc, compiler.getSourceManager(), + compiler.getLangOpts()) + == "assert")) + { + return true; + } + blockState.dynamicCastVars.insert( + { { varDecl, dynamicCastExpr->getTypeAsWritten().getTypePtr() }, + compat::getBeginLoc(dynamicCastExpr) }); return true; } |