1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
10 #ifndef LO_CLANG_SHARED_PLUGINS
18 // Warn about checks whether a container is empty done via an (expensive) call to obtain the
19 // container's size. For now only handles cases involving strlen.
23 BinaryOperatorKind
reverse(BinaryOperatorKind op
)
43 class Empty
: public loplugin::FilteringPlugin
<Empty
>
46 explicit Empty(loplugin::InstantiationData
const& data
)
47 : FilteringPlugin(data
)
51 bool VisitBinaryOperator(BinaryOperator
const* expr
)
53 if (expr
->isRelationalOp() || expr
->isEqualityOp())
55 visitComparison(expr
);
61 void run() override
{ TraverseDecl(compiler
.getASTContext().getTranslationUnitDecl()); }
63 void visitComparison(BinaryOperator
const* expr
, CallExpr
const* lhs
, Expr
const* rhs
,
64 BinaryOperatorKind op
)
66 auto const fdecl
= lhs
->getDirectCallee();
71 loplugin::DeclCheck
dc(fdecl
);
72 if (!(dc
.Function("strlen").StdNamespace() || dc
.Function("strlen").GlobalNamespace()))
76 if (rhs
->isValueDependent())
80 auto const val
= compat::getIntegerConstantExpr(rhs
, compiler
.getASTContext());
88 if (val
->getExtValue() == 1)
90 report(DiagnosticsEngine::Warning
,
91 "replace a comparison like 'strlen(e) < 1' with 'e[0] == '\\0''",
93 << expr
->getSourceRange();
97 if (val
->getExtValue() == 0)
99 report(DiagnosticsEngine::Warning
,
100 "replace a comparison like 'strlen(e) > 0' with 'e[0] != '\\0''",
102 << expr
->getSourceRange();
106 if (val
->getExtValue() == 0)
108 report(DiagnosticsEngine::Warning
,
109 "replace a comparison like 'strlen(e) <= 0' with 'e[0] == '\\0''",
111 << expr
->getSourceRange();
115 if (val
->getExtValue() == 1)
117 report(DiagnosticsEngine::Warning
,
118 "replace a comparison like 'strlen(e) >= 1' with 'e[0] != '\\0''",
120 << expr
->getSourceRange();
124 if (val
->getExtValue() == 0)
126 report(DiagnosticsEngine::Warning
,
127 "replace a comparison like 'strlen(e) == 0' with 'e[0] == '\\0''",
129 << expr
->getSourceRange();
133 if (val
->getExtValue() == 0)
135 report(DiagnosticsEngine::Warning
,
136 "replace a comparison like 'strlen(e) != 0' with 'e[0] != '\\0''",
138 << expr
->getSourceRange();
146 void visitComparison(BinaryOperator
const* expr
)
148 if (ignoreLocation(expr
))
152 if (auto const call
= dyn_cast
<CallExpr
>(expr
->getLHS()->IgnoreParenImpCasts()))
154 visitComparison(expr
, call
, expr
->getRHS(), expr
->getOpcode());
156 else if (auto const call
= dyn_cast
<CallExpr
>(expr
->getRHS()->IgnoreParenImpCasts()))
158 visitComparison(expr
, call
, expr
->getLHS(), reverse(expr
->getOpcode()));
163 loplugin::Plugin::Registration
<Empty
> emptyRegistration("empty");
166 #endif // LO_CLANG_SHARED_PLUGINS
168 /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */