summaryrefslogtreecommitdiff
path: root/compilerplugins
diff options
context:
space:
mode:
authorNoel Grandin <noel.grandin@collabora.co.uk>2017-04-07 09:08:35 +0200
committerNoel Grandin <noel.grandin@collabora.co.uk>2017-04-07 12:16:13 +0000
commitbe8b9b4d29abb951aea0ea195541143d256954dc (patch)
treef35cddad2b45e189b23d881cb7c194845eb5c933 /compilerplugins
parent7d98edfa4955ab6280655a9678d6a913845fa2f3 (diff)
loplugin:redundantcast find cstyle arithmetic casts
Change-Id: If7c259f0d12a41182f476ddb558f7cb5f76f9577 Reviewed-on: https://gerrit.libreoffice.org/36253 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
Diffstat (limited to 'compilerplugins')
-rw-r--r--compilerplugins/clang/redundantcast.cxx104
-rw-r--r--compilerplugins/clang/test/redundantcast.cxx2
2 files changed, 50 insertions, 56 deletions
diff --git a/compilerplugins/clang/redundantcast.cxx b/compilerplugins/clang/redundantcast.cxx
index 72391256b285..a229f95044c7 100644
--- a/compilerplugins/clang/redundantcast.cxx
+++ b/compilerplugins/clang/redundantcast.cxx
@@ -187,6 +187,7 @@ public:
private:
bool visitBinOp(BinaryOperator const * expr);
+ bool isOkToRemoveArithmeticCast(QualType t1, QualType t2, const Expr* subExpr);
};
bool RedundantCast::VisitImplicitCastExpr(const ImplicitCastExpr * expr) {
@@ -323,67 +324,45 @@ bool RedundantCast::VisitCStyleCastExpr(CStyleCastExpr const * expr) {
}
auto t1 = getSubExprAsWritten(expr)->getType();
auto t2 = expr->getTypeAsWritten();
- if (loplugin::TypeCheck(t1).Enum() && t1 == t2) {
- report(
- DiagnosticsEngine::Warning,
- "redundant cstyle enum cast from %0 to %1", expr->getExprLoc())
- << t1 << t2 << expr->getSourceRange();
+ if (t1 != t2) {
return true;
}
- bool bBuiltinType = t1->isSpecificBuiltinType(BuiltinType::Bool)
- || t1->isSpecificBuiltinType(BuiltinType::Void)
- || t1->isSpecificBuiltinType(BuiltinType::Float)
- || t1->isSpecificBuiltinType(BuiltinType::Double)
- || t1->isSpecificBuiltinType(BuiltinType::UChar)
- || t1->isSpecificBuiltinType(BuiltinType::Char_U)
- || t1->isSpecificBuiltinType(BuiltinType::SChar)
- || t1->isSpecificBuiltinType(BuiltinType::Char_S)
- || t1->isSpecificBuiltinType(BuiltinType::Char16)
- || t1->isSpecificBuiltinType(BuiltinType::Char32)
- || t1->isSpecificBuiltinType(BuiltinType::WChar_U)
- || t1->isSpecificBuiltinType(BuiltinType::WChar_S);
- if ((bBuiltinType || loplugin::TypeCheck(t1).Typedef()) && t1 == t2)
- {
- // Ignore FD_ISSET expanding to "...(SOCKET)(fd)..." in some Microsoft
- // winsock2.h (TODO: improve heuristic of determining that the whole
- // expr is part of a single macro body expansion):
- auto l1 = expr->getLocStart();
- while (compiler.getSourceManager().isMacroArgExpansion(l1)) {
- l1 = compiler.getSourceManager().getImmediateMacroCallerLoc(l1);
- }
- auto l2 = expr->getExprLoc();
- while (compiler.getSourceManager().isMacroArgExpansion(l2)) {
- l2 = compiler.getSourceManager().getImmediateMacroCallerLoc(l2);
- }
- auto l3 = expr->getLocEnd();
- while (compiler.getSourceManager().isMacroArgExpansion(l3)) {
- l3 = compiler.getSourceManager().getImmediateMacroCallerLoc(l3);
- }
- if (compiler.getSourceManager().isMacroBodyExpansion(l1)
- && compiler.getSourceManager().isMacroBodyExpansion(l2)
- && compiler.getSourceManager().isMacroBodyExpansion(l3)
- && ignoreLocation(compiler.getSourceManager().getSpellingLoc(l2)))
- {
- return true;
- }
- report(
- DiagnosticsEngine::Warning,
- "redundant cstyle cast from %0 to %1", expr->getExprLoc())
- << t1 << t2 << expr->getSourceRange();
+ if (!t1->isBuiltinType() && !loplugin::TypeCheck(t1).Enum() && !loplugin::TypeCheck(t1).Typedef()) {
return true;
}
- return true;
-}
-
-bool RedundantCast::VisitCXXStaticCastExpr(CXXStaticCastExpr const * expr) {
- if (ignoreLocation(expr)) {
+ if (!isOkToRemoveArithmeticCast(t1, t2, expr->getSubExpr())) {
return true;
}
- auto t1 = getSubExprAsWritten(expr)->getType();
- auto t2 = expr->getTypeAsWritten();
- if (t1.getCanonicalType() != t2.getCanonicalType()) {
+ // Ignore FD_ISSET expanding to "...(SOCKET)(fd)..." in some Microsoft
+ // winsock2.h (TODO: improve heuristic of determining that the whole
+ // expr is part of a single macro body expansion):
+ auto l1 = expr->getLocStart();
+ while (compiler.getSourceManager().isMacroArgExpansion(l1)) {
+ l1 = compiler.getSourceManager().getImmediateMacroCallerLoc(l1);
+ }
+ auto l2 = expr->getExprLoc();
+ while (compiler.getSourceManager().isMacroArgExpansion(l2)) {
+ l2 = compiler.getSourceManager().getImmediateMacroCallerLoc(l2);
+ }
+ auto l3 = expr->getLocEnd();
+ while (compiler.getSourceManager().isMacroArgExpansion(l3)) {
+ l3 = compiler.getSourceManager().getImmediateMacroCallerLoc(l3);
+ }
+ if (compiler.getSourceManager().isMacroBodyExpansion(l1)
+ && compiler.getSourceManager().isMacroBodyExpansion(l2)
+ && compiler.getSourceManager().isMacroBodyExpansion(l3)
+ && ignoreLocation(compiler.getSourceManager().getSpellingLoc(l2)))
+ {
return true;
}
+ report(
+ DiagnosticsEngine::Warning,
+ "redundant cstyle cast from %0 to %1", expr->getExprLoc())
+ << t1 << t2 << expr->getSourceRange();
+ return true;
+}
+
+bool RedundantCast::isOkToRemoveArithmeticCast(QualType t1, QualType t2, const Expr* subExpr) {
// Don't warn if the types are arithmetic (in the C++ meaning), and: either
// at least one is a typedef (and if both are typedefs,they're different),
// or the sub-expression involves some operation that is likely to change
@@ -395,9 +374,24 @@ bool RedundantCast::VisitCXXStaticCastExpr(CXXStaticCastExpr const * expr) {
&& ((t1 != t2
&& (loplugin::TypeCheck(t1).Typedef()
|| loplugin::TypeCheck(t2).Typedef()))
- || isArithmeticOp(expr->getSubExpr())
- || isa<IntegerLiteral>(expr->getSubExpr()->IgnoreParenImpCasts())))
+ || isArithmeticOp(subExpr)
+ || isa<IntegerLiteral>(subExpr->IgnoreParenImpCasts())))
{
+ return false;
+ }
+ return true;
+}
+
+bool RedundantCast::VisitCXXStaticCastExpr(CXXStaticCastExpr const * expr) {
+ if (ignoreLocation(expr)) {
+ return true;
+ }
+ auto t1 = getSubExprAsWritten(expr)->getType();
+ auto t2 = expr->getTypeAsWritten();
+ if (t1.getCanonicalType() != t2.getCanonicalType()) {
+ return true;
+ }
+ if (!isOkToRemoveArithmeticCast(t1, t2, expr->getSubExpr())) {
return true;
}
// Don't warn if the types are 'void *' and at least one involves a typedef
diff --git a/compilerplugins/clang/test/redundantcast.cxx b/compilerplugins/clang/test/redundantcast.cxx
index a7516c1a058f..73b8ef072411 100644
--- a/compilerplugins/clang/test/redundantcast.cxx
+++ b/compilerplugins/clang/test/redundantcast.cxx
@@ -30,7 +30,7 @@ int main() {
f2(const_cast<char const *>(p2)); // expected-error {{redundant const_cast from 'const char *' to 'const char *' [loplugin:redundantcast]}}
f2(const_cast<char const * const>(p2)); // expected-error {{redundant const_cast from 'const char *' to 'const char *const' [loplugin:redundantcast]}}
- Enum1 e = (Enum1)Enum1::X; // expected-error {{redundant cstyle enum cast from 'Enum1' to 'Enum1' [loplugin:redundantcast]}}
+ Enum1 e = (Enum1)Enum1::X; // expected-error {{redundant cstyle cast from 'Enum1' to 'Enum1' [loplugin:redundantcast]}}
(void)e;
}