summaryrefslogtreecommitdiff
path: root/compilerplugins/clang/salbool.cxx
diff options
context:
space:
mode:
authorStephan Bergmann <sbergman@redhat.com>2016-06-19 21:29:43 +0200
committerStephan Bergmann <sbergman@redhat.com>2016-06-19 21:29:43 +0200
commit82da3d95c1bb2ba410a89fc1721b1ccb4f25b7cb (patch)
tree87a34da45d7048338a097c8a578354ba326c24d8 /compilerplugins/clang/salbool.cxx
parentc3a5012c5a9699040698505d3e34672382c026b8 (diff)
loplugin:salbool: Implicit conversions from non-Boolean fundamental types
Change-Id: I67eac95686678e6f5a2d60798535b2c65a9ba5d7
Diffstat (limited to 'compilerplugins/clang/salbool.cxx')
-rw-r--r--compilerplugins/clang/salbool.cxx50
1 files changed, 50 insertions, 0 deletions
diff --git a/compilerplugins/clang/salbool.cxx b/compilerplugins/clang/salbool.cxx
index f70135805fa7..f08b1c0da0c0 100644
--- a/compilerplugins/clang/salbool.cxx
+++ b/compilerplugins/clang/salbool.cxx
@@ -16,6 +16,7 @@
#include "compat.hxx"
#include "plugin.hxx"
+#include "typecheck.hxx"
namespace {
@@ -143,6 +144,8 @@ public:
bool VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr * expr);
+ bool VisitImplicitCastExpr(ImplicitCastExpr * expr);
+
bool VisitReturnStmt(ReturnStmt const * stmt);
bool WalkUpFromParmVarDecl(ParmVarDecl const * decl);
@@ -382,6 +385,53 @@ bool SalBool::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr * expr) {
return true;
}
+bool SalBool::VisitImplicitCastExpr(ImplicitCastExpr * expr) {
+ if (ignoreLocation(expr)) {
+ return true;
+ }
+ if (!isSalBool(expr->getType())) {
+ return true;
+ }
+ auto l = expr->getLocStart();
+ while (compiler.getSourceManager().isMacroArgExpansion(l)) {
+ l = compiler.getSourceManager().getImmediateMacroCallerLoc(l);
+ }
+ if (compat::isMacroBodyExpansion(compiler, l)) {
+ auto n = Lexer::getImmediateMacroName(
+ l, compiler.getSourceManager(), compiler.getLangOpts());
+ if (n == "sal_False" || n == "sal_True") {
+ return true;
+ }
+ }
+ auto e1 = expr->getSubExprAsWritten();
+ auto t = e1->getType();
+ if (!t->isFundamentalType() || loplugin::TypeCheck(t).AnyBoolean()) {
+ return true;
+ }
+ auto e2 = dyn_cast<ConditionalOperator>(e1);
+ if (e2 != nullptr) {
+ auto ic1 = dyn_cast<ImplicitCastExpr>(
+ e2->getTrueExpr()->IgnoreParens());
+ auto ic2 = dyn_cast<ImplicitCastExpr>(
+ e2->getFalseExpr()->IgnoreParens());
+ if (ic1 != nullptr && ic2 != nullptr
+ && ic1->getType()->isSpecificBuiltinType(BuiltinType::Int)
+ && (loplugin::TypeCheck(ic1->getSubExprAsWritten()->getType())
+ .AnyBoolean())
+ && ic2->getType()->isSpecificBuiltinType(BuiltinType::Int)
+ && (loplugin::TypeCheck(ic2->getSubExprAsWritten()->getType())
+ .AnyBoolean()))
+ {
+ return true;
+ }
+ }
+ report(
+ DiagnosticsEngine::Warning, "conversion from %0 to sal_Bool",
+ expr->getLocStart())
+ << t << expr->getSourceRange();
+ return true;
+}
+
bool SalBool::VisitReturnStmt(ReturnStmt const * stmt) {
// Just enough to avoid warnings in rtl_getUriCharClass (sal/rtl/uri.cxx),
// which has