summaryrefslogtreecommitdiffstats
path: root/compilerplugins/clang/implicitboolconversion.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'compilerplugins/clang/implicitboolconversion.cxx')
-rw-r--r--compilerplugins/clang/implicitboolconversion.cxx114
1 files changed, 63 insertions, 51 deletions
diff --git a/compilerplugins/clang/implicitboolconversion.cxx b/compilerplugins/clang/implicitboolconversion.cxx
index bc0b74932b71..64bc97ff4999 100644
--- a/compilerplugins/clang/implicitboolconversion.cxx
+++ b/compilerplugins/clang/implicitboolconversion.cxx
@@ -17,8 +17,6 @@
#include "clang/Basic/Builtins.h"
-#include "config_clang.h"
-
#include "check.hxx"
#include "compat.hxx"
#include "plugin.hxx"
@@ -32,7 +30,7 @@ Expr const * ignoreParenAndTemporaryMaterialization(Expr const * expr) {
if (e == nullptr) {
return expr;
}
- expr = compat::getSubExpr(e);
+ expr = e->getSubExpr();
}
}
@@ -65,14 +63,15 @@ QualType reconstructTemplateArgumentType(
SubstTemplateTypeParmType const * parmType)
{
TemplateParameterList const * ps = decl->getTemplateParameters();
- auto i = std::find(ps->begin(), ps->end(), parmType->getReplacedParameter()->getDecl());
+ auto i = std::find(ps->begin(), ps->end(), compat::getReplacedParameter(parmType));
if (i == ps->end()) {
return {};
}
- if (ps->size() != specializationType->getNumArgs()) { //TODO
+ auto const args = specializationType->template_arguments();
+ if (ps->size() != args.size()) { //TODO
return {};
}
- TemplateArgument const & arg = specializationType->getArg(i - ps->begin());
+ TemplateArgument const & arg = args[i - ps->begin()];
if (arg.getKind() != TemplateArgument::Type) {
return {};
}
@@ -181,15 +180,24 @@ bool isBoolExpr(Expr const * expr) {
(void)op;
TemplateDecl const * d
= t->getTemplateName().getAsTemplateDecl();
- if (d == nullptr
- || (d->getQualifiedNameAsString()
- != "com::sun::star::uno::Sequence")
- || t->getNumArgs() != 1
- || t->getArg(0).getKind() != TemplateArgument::Type)
+ if (d == nullptr) {
+ break;
+ }
+ auto const dc = loplugin::DeclCheck(d->getTemplatedDecl());
+ auto const args = t->template_arguments();
+ if (dc.ClassOrStruct("array").StdNamespace() && args.size() >= 2
+ && args[0].getKind() == TemplateArgument::Type)
+ {
+ ty = args[0].getAsType();
+ } else if (dc.Class("Sequence").Namespace("uno").Namespace("star").Namespace("sun")
+ .Namespace("com").GlobalNamespace()
+ && args.size() == 1
+ && args[0].getKind() == TemplateArgument::Type)
{
+ ty = args[0].getAsType();
+ } else {
break;
}
- ty = t->getArg(0).getAsType();
}
stack.pop();
if (stack.empty()) {
@@ -253,27 +261,8 @@ public:
bool TraverseBinaryOperator(BinaryOperator * expr);
-#if CLANG_VERSION < 110000
- bool TraverseBinLT(BinaryOperator * expr) { return TraverseBinaryOperator(expr); }
- bool TraverseBinLE(BinaryOperator * expr) { return TraverseBinaryOperator(expr); }
- bool TraverseBinGT(BinaryOperator * expr) { return TraverseBinaryOperator(expr); }
- bool TraverseBinGE(BinaryOperator * expr) { return TraverseBinaryOperator(expr); }
- bool TraverseBinEQ(BinaryOperator * expr) { return TraverseBinaryOperator(expr); }
- bool TraverseBinNE(BinaryOperator * expr) { return TraverseBinaryOperator(expr); }
- bool TraverseBinAssign(BinaryOperator * expr) { return TraverseBinaryOperator(expr); }
-#endif
-
bool TraverseCompoundAssignOperator(CompoundAssignOperator * expr);
-#if CLANG_VERSION < 110000
- bool TraverseBinAndAssign(CompoundAssignOperator * expr)
- { return TraverseCompoundAssignOperator(expr); }
- bool TraverseBinOrAssign(CompoundAssignOperator * expr)
- { return TraverseCompoundAssignOperator(expr); }
- bool TraverseBinXorAssign(CompoundAssignOperator * expr)
- { return TraverseCompoundAssignOperator(expr); }
-#endif
-
bool TraverseInitListExpr(InitListExpr * expr);
bool TraverseReturnStmt(ReturnStmt * stmt);
@@ -425,9 +414,10 @@ bool ImplicitBoolConversion::TraverseCXXMemberCallExpr(CXXMemberCallExpr * expr)
= ct->getTemplateName().getAsTemplateDecl();
if (td != nullptr) {
//TODO: fix this superficial nonsense check:
- if (ct->getNumArgs() >= 1
- && ct->getArg(0).getKind() == TemplateArgument::Type
- && (loplugin::TypeCheck(ct->getArg(0).getAsType())
+ auto const args = ct->template_arguments();
+ if (args.size() >= 1
+ && args[0].getKind() == TemplateArgument::Type
+ && (loplugin::TypeCheck(args[0].getAsType())
.AnyBoolean()))
{
continue;
@@ -613,7 +603,7 @@ bool ImplicitBoolConversion::TraverseCompoundAssignOperator(CompoundAssignOperat
{
report(
DiagnosticsEngine::Warning, "mix of %0 and %1 in operator %2",
- compat::getBeginLoc(expr->getRHS()))
+ expr->getRHS()->getBeginLoc())
<< expr->getLHS()->getType()
<< expr->getRHS()->IgnoreParenImpCasts()->getType()
<< expr->getOpcodeStr()
@@ -701,13 +691,33 @@ bool ImplicitBoolConversion::VisitImplicitCastExpr(
if (isBool(compat::getSubExprAsWritten(expr)) && !isBool(expr)) {
// Ignore NoOp from 'sal_Bool' (aka 'unsigned char') to 'const unsigned
// char' in makeAny(b) with b of type sal_Bool:
- if (expr->getCastKind() != CK_NoOp) {
- if (nested.empty()) {
- reportWarning(expr);
- } else {
- nested.top().push_back(expr);
+ if (expr->getCastKind() == CK_NoOp) {
+ return true;
+ }
+ // Ignore implicit conversions from bool to int in
+ //
+ // #define _G_STR_NONNULL(x) (x + !x)
+ //
+ // from
+ // <https://gitlab.gnome.org/GNOME/glib/-/commit/48730d2b30473c5eeda2badf9a65d380304477c3>
+ // "gstrfuncs: Add back x + !x warning workaround":
+ if (auto const sub = dyn_cast<UnaryOperator>(compat::getSubExprAsWritten(expr))) {
+ if (sub->getOpcode() == UO_LNot) {
+ auto const l = expr->getBeginLoc();
+ if (compiler.getSourceManager().isMacroBodyExpansion(l)
+ && Lexer::getImmediateMacroName(
+ l, compiler.getSourceManager(), compiler.getLangOpts())
+ == "_G_STR_NONNULL")
+ {
+ return true;
+ }
}
}
+ if (nested.empty()) {
+ reportWarning(expr);
+ } else {
+ nested.top().push_back(expr);
+ }
return true;
}
if (auto const sub = dyn_cast<ExplicitCastExpr>(
@@ -729,7 +739,7 @@ bool ImplicitBoolConversion::VisitImplicitCastExpr(
DiagnosticsEngine::Warning,
("explicit conversion (%0) from %1 to %2 implicitly cast back"
" to %3"),
- compat::getBeginLoc(expr))
+ expr->getBeginLoc())
<< sub->getCastKindName() << subsub->getType() << sub->getType()
<< expr->getType() << expr->getSourceRange();
return true;
@@ -746,7 +756,7 @@ bool ImplicitBoolConversion::VisitImplicitCastExpr(
report(
DiagnosticsEngine::Warning,
"implicit conversion (%0) of call argument from %1 to %2",
- compat::getBeginLoc(expr))
+ expr->getBeginLoc())
<< expr->getCastKindName() << expr->getSubExpr()->getType()
<< expr->getType() << expr->getSourceRange();
return true;
@@ -761,7 +771,7 @@ bool ImplicitBoolConversion::VisitMaterializeTemporaryExpr(
if (ignoreLocation(expr)) {
return true;
}
- if (auto const sub = dyn_cast<ExplicitCastExpr>(compat::getSubExpr(expr))) {
+ if (auto const sub = dyn_cast<ExplicitCastExpr>(expr->getSubExpr())) {
auto const subsub = compat::getSubExprAsWritten(sub);
if (subsub->getType().IgnoreParens() == expr->getType().IgnoreParens()
&& isBool(subsub))
@@ -770,7 +780,7 @@ bool ImplicitBoolConversion::VisitMaterializeTemporaryExpr(
DiagnosticsEngine::Warning,
("explicit conversion (%0) from %1 to %2 implicitly converted"
" back to %3"),
- compat::getBeginLoc(expr))
+ expr->getBeginLoc())
<< sub->getCastKindName() << subsub->getType() << sub->getType()
<< expr->getType() << expr->getSourceRange();
return true;
@@ -857,11 +867,12 @@ void ImplicitBoolConversion::checkCXXConstructExpr(
= td->getTemplateParameters();
auto k = std::find(
ps->begin(), ps->end(),
- t2->getReplacedParameter()->getDecl());
+ compat::getReplacedParameter(t2));
if (k != ps->end()) {
- if (ps->size() == t1->getNumArgs()) { //TODO
- TemplateArgument const & arg = t1->getArg(
- k - ps->begin());
+ auto const args = t1->template_arguments();
+ if (ps->size() == args.size()) { //TODO
+ TemplateArgument const & arg = args[
+ k - ps->begin()];
if (arg.getKind() == TemplateArgument::Type
&& (loplugin::TypeCheck(arg.getAsType())
.AnyBoolean()))
@@ -883,8 +894,9 @@ void ImplicitBoolConversion::reportWarning(ImplicitCastExpr const * expr) {
if (expr->getCastKind() == CK_ConstructorConversion) {
auto const t1 = expr->getType();
if (auto const t2 = t1->getAs<TemplateSpecializationType>()) {
- assert(t2->getNumArgs() >= 1);
- auto const a = t2->getArg(0);
+ auto const args = t2->template_arguments();
+ assert(args.size() >= 1);
+ auto const a = args[0];
if (a.getKind() == TemplateArgument::Type && a.getAsType()->isBooleanType()
&& (loplugin::TypeCheck(t1).TemplateSpecializationClass()
.ClassOrStruct("atomic").StdNamespace()))
@@ -895,7 +907,7 @@ void ImplicitBoolConversion::reportWarning(ImplicitCastExpr const * expr) {
}
report(
DiagnosticsEngine::Warning,
- "implicit conversion (%0) from %1 to %2", compat::getBeginLoc(expr))
+ "implicit conversion (%0) from %1 to %2", expr->getBeginLoc())
<< expr->getCastKindName() << expr->getSubExprAsWritten()->getType()
<< expr->getType() << expr->getSourceRange();
}