summaryrefslogtreecommitdiff
path: root/compilerplugins
diff options
context:
space:
mode:
authorStephan Bergmann <sbergman@redhat.com>2019-02-18 09:05:34 +0100
committerStephan Bergmann <sbergman@redhat.com>2019-02-18 10:22:48 +0100
commit893ee431803629111eb9271f72bde6a82cafebec (patch)
tree8535eadebe9edfd98a140835eff1efbf946322a3 /compilerplugins
parent0887b47f9b272a8256a6889a912394e7cbda4c6f (diff)
Tell about presumed corresponding negated operator
Change-Id: Ic7ed64ecc4902853dc7431294484abb74e8da65b Reviewed-on: https://gerrit.libreoffice.org/67953 Tested-by: Jenkins Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
Diffstat (limited to 'compilerplugins')
-rw-r--r--compilerplugins/clang/simplifybool.cxx17
-rw-r--r--compilerplugins/clang/test/simplifybool.cxx3
2 files changed, 14 insertions, 6 deletions
diff --git a/compilerplugins/clang/simplifybool.cxx b/compilerplugins/clang/simplifybool.cxx
index 40c5b6fc48ba..4f7e418f0655 100644
--- a/compilerplugins/clang/simplifybool.cxx
+++ b/compilerplugins/clang/simplifybool.cxx
@@ -53,15 +53,15 @@ Expr const * getSubExprOfLogicalNegation(Expr const * expr) {
? nullptr : e->getSubExpr();
}
-bool existsOperator(CompilerInstance& compiler, clang::RecordType const * recordType, BinaryOperator::Opcode opcode) {
+FunctionDecl const * findOperator(CompilerInstance& compiler, clang::RecordType const * recordType, BinaryOperator::Opcode opcode) {
OverloadedOperatorKind over = BinaryOperator::getOverloadedOperator(opcode);
CXXRecordDecl const * recordDecl = dyn_cast<CXXRecordDecl>(recordType->getDecl());
if (!recordDecl)
- return false;
+ return nullptr;
// search for member overloads
for (auto it = recordDecl->method_begin(); it != recordDecl->method_end(); ++it) {
if (it->getOverloadedOperator() == over) {
- return true;
+ return *it;
}
}
// search for free function overloads
@@ -80,9 +80,9 @@ bool existsOperator(CompilerInstance& compiler, clang::RecordType const * record
if (!lvalue)
continue;
if (lvalue->getPointeeType().getTypePtr() == recordType)
- return true;
+ return f;
}
- return false;
+ return nullptr;
}
enum class Value { Unknown, False, True };
@@ -236,7 +236,8 @@ bool SimplifyBool::VisitUnaryLNot(UnaryOperator const * expr) {
if (!t->isRecordType())
return true;
auto recordType = dyn_cast<RecordType>(t);
- if (!existsOperator(compiler, recordType, negatedOpcode))
+ auto const negOp = findOperator(compiler, recordType, negatedOpcode);
+ if (!negOp)
return true;
// if we are inside a similar operator, ignore, eg. operator!= is often defined by calling !operator==
if (m_insideFunctionDecl && m_insideFunctionDecl->getNumParams() >= 1) {
@@ -254,6 +255,10 @@ bool SimplifyBool::VisitUnaryLNot(UnaryOperator const * expr) {
("logical negation of comparison operator, can be simplified by inverting operator"),
compat::getBeginLoc(expr))
<< expr->getSourceRange();
+ report(
+ DiagnosticsEngine::Note, "the presumed corresponding negated operator is declared here",
+ negOp->getLocation())
+ << negOp->getSourceRange();
}
return true;
}
diff --git a/compilerplugins/clang/test/simplifybool.cxx b/compilerplugins/clang/test/simplifybool.cxx
index 64288253c8e2..8428502ff01d 100644
--- a/compilerplugins/clang/test/simplifybool.cxx
+++ b/compilerplugins/clang/test/simplifybool.cxx
@@ -8,6 +8,7 @@
*/
#include <rtl/ustring.hxx>
+// expected-note@rtl/ustring.hxx:* 2 {{the presumed corresponding negated operator is declared here [loplugin:simplifybool]}}
namespace group1
{
@@ -75,6 +76,7 @@ struct Record2
{
bool operator==(const Record2&) const;
bool operator!=(const Record2&) const;
+ // expected-note@-1 {{the presumed corresponding negated operator is declared here [loplugin:simplifybool]}}
};
struct Record3
@@ -83,6 +85,7 @@ struct Record3
bool operator==(const Record3&, const Record3&);
bool operator!=(const Record3&, const Record3&);
+// expected-note@-1 {{the presumed corresponding negated operator is declared here [loplugin:simplifybool]}}
void testRecord()
{