summaryrefslogtreecommitdiff
path: root/compilerplugins
diff options
context:
space:
mode:
authorStephan Bergmann <sbergman@redhat.com>2015-03-31 13:18:16 +0200
committerStephan Bergmann <sbergman@redhat.com>2015-03-31 13:18:16 +0200
commit90ed482496be0186e95c89e60035da555261de4e (patch)
tree332c655ef15408a74ea03e6ce4b3ece61baa387b /compilerplugins
parent698a6d4ab6e2f8485ed4e1d8322ac74c7087d621 (diff)
Reduce to static_cast any reinterpret_cast from void pointers
Change-Id: I514e183571e4ac109f59c4bdfccdc553c36c26ee
Diffstat (limited to 'compilerplugins')
-rw-r--r--compilerplugins/clang/redundantcast.cxx54
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);
}