Kaydet (Commit) ad9cfbcf authored tarafından Stephan Bergmann's avatar Stephan Bergmann

Don't exclude a var from loplugin:salbool merely because of use in >>=

Change-Id: I1b8a3dfa1dc6b351ab0903a74eae19dfa6d0888d
üst 5af78ee8
...@@ -70,37 +70,72 @@ OverrideKind getOverrideKind(FunctionDecl const * decl) { ...@@ -70,37 +70,72 @@ OverrideKind getOverrideKind(FunctionDecl const * decl) {
return OverrideKind::MAYBE; return OverrideKind::MAYBE;
} }
enum class BoolOverloadKind { No, Yes, CheckNext };
BoolOverloadKind isBoolOverloadOf(
FunctionDecl const * f, FunctionDecl const * decl, bool mustBeDeleted)
{
if (!mustBeDeleted || f->isDeleted()) {
unsigned n = decl->getNumParams();
if (f->getNumParams() == n) {
bool hasSB = false;
for (unsigned i = 0; i != n; ++i) {
QualType t1 { decl->getParamDecl(i)->getType() };
bool isSB = isSalBool(t1);
bool isSBRef = !isSB && t1->isReferenceType()
&& isSalBool(t1.getNonReferenceType());
QualType t2 { f->getParamDecl(i)->getType() };
if (!(isSB
? t2->isBooleanType()
: isSBRef
? (t2->isReferenceType()
&& t2.getNonReferenceType()->isBooleanType())
: t2.getCanonicalType() == t1.getCanonicalType()))
{
return BoolOverloadKind::CheckNext;
}
hasSB |= isSB || isSBRef;
}
return hasSB ? BoolOverloadKind::Yes : BoolOverloadKind::No;
// cheaply protect against the case where decl would have no
// sal_Bool parameters at all and would match itself
}
}
return BoolOverloadKind::CheckNext;
}
//TODO: current implementation is not at all general, just tests what we //TODO: current implementation is not at all general, just tests what we
// encounter in practice: // encounter in practice:
bool hasBoolOverload(FunctionDecl const * decl, bool mustBeDeleted) { bool hasBoolOverload(FunctionDecl const * decl, bool mustBeDeleted) {
unsigned n = decl->getNumParams(); auto ctx = decl->getDeclContext();
auto res = decl->getDeclContext()->lookup(decl->getDeclName()); if (!ctx->isLookupContext()) {
return false;
}
auto res = ctx->lookup(decl->getDeclName());
for (auto d = res.begin(); d != res.end(); ++d) { for (auto d = res.begin(); d != res.end(); ++d) {
FunctionDecl const * f = dyn_cast<FunctionDecl>(*d); if (auto f = dyn_cast<FunctionDecl>(*d)) {
if (f != nullptr && (!mustBeDeleted || f->isDeleted())) { switch (isBoolOverloadOf(f, decl, mustBeDeleted)) {
if (f->getNumParams() == n) { case BoolOverloadKind::No:
bool hasSB = false; return false;
for (unsigned i = 0; i != n; ++i) { case BoolOverloadKind::Yes:
QualType t1 { decl->getParamDecl(i)->getType() }; return true;
bool isSB = isSalBool(t1); case BoolOverloadKind::CheckNext:
bool isSBRef = !isSB && t1->isReferenceType() break;
&& isSalBool(t1.getNonReferenceType()); }
QualType t2 { f->getParamDecl(i)->getType() }; } else if (auto ftd = dyn_cast<FunctionTemplateDecl>(*d)) {
if (!(isSB for (auto f: ftd->specializations()) {
? t2->isBooleanType() if (f->getTemplateSpecializationKind()
: isSBRef == TSK_ExplicitSpecialization)
? (t2->isReferenceType() {
&& t2.getNonReferenceType()->isBooleanType()) switch (isBoolOverloadOf(f, decl, mustBeDeleted)) {
: t2 == t1)) case BoolOverloadKind::No:
{ return false;
goto next; case BoolOverloadKind::Yes:
return true;
case BoolOverloadKind::CheckNext:
break;
} }
hasSB |= isSB || isSBRef;
} }
return hasSB;
// cheaply protect against the case where decl would have no
// sal_Bool parameters at all and would match itself
next:;
} }
} }
} }
...@@ -226,14 +261,17 @@ bool SalBool::VisitCallExpr(CallExpr * expr) { ...@@ -226,14 +261,17 @@ bool SalBool::VisitCallExpr(CallExpr * expr) {
if (d != nullptr) { if (d != nullptr) {
FunctionDecl const * fd = dyn_cast<FunctionDecl>(d); FunctionDecl const * fd = dyn_cast<FunctionDecl>(d);
if (fd != nullptr) { if (fd != nullptr) {
PointerType const * pt = fd->getType()->getAs<PointerType>(); if (!hasBoolOverload(fd, false)) {
QualType t2(pt == nullptr ? fd->getType() : pt->getPointeeType()); PointerType const * pt = fd->getType()->getAs<PointerType>();
ft = t2->getAs<FunctionProtoType>(); QualType t2(
assert( pt == nullptr ? fd->getType() : pt->getPointeeType());
ft != nullptr || !compiler.getLangOpts().CPlusPlus ft = t2->getAs<FunctionProtoType>();
|| (fd->getBuiltinID() != Builtin::NotBuiltin assert(
&& isa<FunctionNoProtoType>(t2))); ft != nullptr || !compiler.getLangOpts().CPlusPlus
// __builtin_*s have no proto type? || (fd->getBuiltinID() != Builtin::NotBuiltin
&& isa<FunctionNoProtoType>(t2)));
// __builtin_*s have no proto type?
}
} else { } else {
VarDecl const * vd = dyn_cast<VarDecl>(d); VarDecl const * vd = dyn_cast<VarDecl>(d);
if (vd != nullptr) { if (vd != nullptr) {
......
...@@ -36,7 +36,7 @@ inline void SAL_CALL convertPropertyValue( target &value , const css::uno::Any ...@@ -36,7 +36,7 @@ inline void SAL_CALL convertPropertyValue( target &value , const css::uno::Any
} }
} }
inline void SAL_CALL convertPropertyValue( sal_Bool & b , const css::uno::Any & a ) void convertPropertyValue(bool & b, const css::uno::Any & a)
{ {
if( !(a >>= b) ) { if( !(a >>= b) ) {
switch( a.getValueType().getTypeClass() ) { switch( a.getValueType().getTypeClass() ) {
...@@ -71,8 +71,8 @@ inline void SAL_CALL convertPropertyValue( sal_Bool & b , const css::uno::Any ...@@ -71,8 +71,8 @@ inline void SAL_CALL convertPropertyValue( sal_Bool & b , const css::uno::Any
} }
} }
void convertPropertyValue(bool & target, css::uno::Any const & source) { void convertPropertyValue(sal_Bool & target, css::uno::Any const & source) {
sal_Bool b; bool b;
convertPropertyValue(b, source); convertPropertyValue(b, source);
target = b; target = b;
} }
......
...@@ -1096,7 +1096,7 @@ static void InterceptLOKStateChangeEvent(const SfxViewFrame* pViewFrame, const c ...@@ -1096,7 +1096,7 @@ static void InterceptLOKStateChangeEvent(const SfxViewFrame* pViewFrame, const c
aEvent.FeatureURL.Path == "NumberFormatPercent" || aEvent.FeatureURL.Path == "NumberFormatPercent" ||
aEvent.FeatureURL.Path == "NumberFormatDate") aEvent.FeatureURL.Path == "NumberFormatDate")
{ {
sal_Bool aBool; bool aBool;
if (aEvent.IsEnabled && (aEvent.State >>= aBool)) if (aEvent.IsEnabled && (aEvent.State >>= aBool))
{ {
...@@ -1105,7 +1105,7 @@ static void InterceptLOKStateChangeEvent(const SfxViewFrame* pViewFrame, const c ...@@ -1105,7 +1105,7 @@ static void InterceptLOKStateChangeEvent(const SfxViewFrame* pViewFrame, const c
} }
else if (aEvent.FeatureURL.Path == "ToggleMergeCells") else if (aEvent.FeatureURL.Path == "ToggleMergeCells")
{ {
sal_Bool aBool; bool aBool;
if (aEvent.IsEnabled && (aEvent.State >>= aBool)) if (aEvent.IsEnabled && (aEvent.State >>= aBool))
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment