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
17 // Warn about checks whether a container is empty done via an (expensive) call to obtain the
18 // container's size. For now only handles cases involving strlen.
22 BinaryOperatorKind
reverse(BinaryOperatorKind op
)
42 class Empty
: public loplugin::FilteringPlugin
<Empty
>
45 explicit Empty(loplugin::InstantiationData
const& data
)
46 : FilteringPlugin(data
)
50 bool VisitBinaryOperator(BinaryOperator
const* expr
)
52 if (expr
->isRelationalOp() || expr
->isEqualityOp())
54 visitComparison(expr
);
60 void run() override
{ TraverseDecl(compiler
.getASTContext().getTranslationUnitDecl()); }
62 void visitComparison(BinaryOperator
const* expr
, CallExpr
const* lhs
, Expr
const* rhs
,
63 BinaryOperatorKind op
)
65 auto const fdecl
= lhs
->getDirectCallee();
70 loplugin::DeclCheck
dc(fdecl
);
71 if (!(dc
.Function("strlen").StdNamespace() || dc
.Function("strlen").GlobalNamespace()))
75 if (rhs
->isValueDependent())
79 auto const val
= rhs
->getIntegerConstantExpr(compiler
.getASTContext());
87 if (val
->getExtValue() == 1)
89 report(DiagnosticsEngine::Warning
,
90 "replace a comparison like 'strlen(e) < 1' with 'e[0] == '\\0''",
92 << expr
->getSourceRange();
96 if (val
->getExtValue() == 0)
98 report(DiagnosticsEngine::Warning
,
99 "replace a comparison like 'strlen(e) > 0' with 'e[0] != '\\0''",
101 << expr
->getSourceRange();
105 if (val
->getExtValue() == 0)
107 report(DiagnosticsEngine::Warning
,
108 "replace a comparison like 'strlen(e) <= 0' with 'e[0] == '\\0''",
110 << expr
->getSourceRange();
114 if (val
->getExtValue() == 1)
116 report(DiagnosticsEngine::Warning
,
117 "replace a comparison like 'strlen(e) >= 1' with 'e[0] != '\\0''",
119 << expr
->getSourceRange();
123 if (val
->getExtValue() == 0)
125 report(DiagnosticsEngine::Warning
,
126 "replace a comparison like 'strlen(e) == 0' with 'e[0] == '\\0''",
128 << expr
->getSourceRange();
132 if (val
->getExtValue() == 0)
134 report(DiagnosticsEngine::Warning
,
135 "replace a comparison like 'strlen(e) != 0' with 'e[0] != '\\0''",
137 << expr
->getSourceRange();
145 void visitComparison(BinaryOperator
const* expr
)
147 if (ignoreLocation(expr
))
151 if (auto const call
= dyn_cast
<CallExpr
>(expr
->getLHS()->IgnoreParenImpCasts()))
153 visitComparison(expr
, call
, expr
->getRHS(), expr
->getOpcode());
155 else if (auto const call
= dyn_cast
<CallExpr
>(expr
->getRHS()->IgnoreParenImpCasts()))
157 visitComparison(expr
, call
, expr
->getLHS(), reverse(expr
->getOpcode()));
162 loplugin::Plugin::Registration
<Empty
> emptyRegistration("empty");
165 #endif // LO_CLANG_SHARED_PLUGINS
167 /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */