summaryrefslogtreecommitdiff
path: root/compilerplugins
diff options
context:
space:
mode:
authorStephan Bergmann <sbergman@redhat.com>2019-10-09 14:25:36 +0200
committerStephan Bergmann <sbergman@redhat.com>2019-10-09 20:42:21 +0200
commit4b0afe968ed62ac65d5f04918f4cda501ecf1619 (patch)
tree861b5911bc3a24517f5e14fccca0d8310a1580b5 /compilerplugins
parent39090afac268f9ae985832c2f08863b41e6c06f2 (diff)
Improve loplugin:redundantpointerops diagnostic messages
Change-Id: If09f5c916f2db98c5d1754d2fbc8f53c502799c9 Reviewed-on: https://gerrit.libreoffice.org/80543 Tested-by: Jenkins Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
Diffstat (limited to 'compilerplugins')
-rw-r--r--compilerplugins/clang/compat.hxx13
-rw-r--r--compilerplugins/clang/redundantpointerops.cxx17
-rw-r--r--compilerplugins/clang/test/redundantpointerops.cxx8
3 files changed, 28 insertions, 10 deletions
diff --git a/compilerplugins/clang/compat.hxx b/compilerplugins/clang/compat.hxx
index cb13f44cfa66..c091c51601f7 100644
--- a/compilerplugins/clang/compat.hxx
+++ b/compilerplugins/clang/compat.hxx
@@ -240,6 +240,19 @@ inline const clang::Expr *getSubExprAsWritten(const clang::CastExpr *This) {
return getSubExprAsWritten(const_cast<clang::CastExpr *>(This));
}
+inline clang::QualType getObjectType(clang::CXXMemberCallExpr const * expr) {
+#if CLANG_VERSION >= 100000
+ return expr->getObjectType();
+#else
+ // <https://github.com/llvm/llvm-project/commit/88559637641e993895337e1047a0bd787fecc647>
+ // "[OpenCL] Improve destructor support in C++ for OpenCL":
+ clang::QualType Ty = expr->getImplicitObjectArgument()->getType();
+ if (Ty->isPointerType())
+ Ty = Ty->getPointeeType();
+ return Ty;
+#endif
+}
+
inline bool isExplicitSpecified(clang::CXXConstructorDecl const * decl) {
#if CLANG_VERSION >= 90000
return decl->getExplicitSpecifier().isExplicit();
diff --git a/compilerplugins/clang/redundantpointerops.cxx b/compilerplugins/clang/redundantpointerops.cxx
index 5406989696c5..dbb3ef7882fd 100644
--- a/compilerplugins/clang/redundantpointerops.cxx
+++ b/compilerplugins/clang/redundantpointerops.cxx
@@ -75,8 +75,10 @@ bool RedundantPointerOps::VisitMemberExpr(MemberExpr const * memberExpr)
{
if (unaryOp->getOpcode() == UO_AddrOf)
report(
- DiagnosticsEngine::Warning, "'&' followed by '->', rather use '.'",
+ DiagnosticsEngine::Warning,
+ "'&' followed by '->' operating on %0, rather use '.'",
compat::getBeginLoc(memberExpr))
+ << memberExpr->getBase()->getType()->getPointeeType()
<< memberExpr->getSourceRange();
}
@@ -84,8 +86,10 @@ bool RedundantPointerOps::VisitMemberExpr(MemberExpr const * memberExpr)
{
if (operatorCallExpr->getOperator() == OO_Amp)
report(
- DiagnosticsEngine::Warning, "'&' followed by '->', rather use '.'",
+ DiagnosticsEngine::Warning,
+ "'&' followed by '->' operating on %0, rather use '.'",
compat::getBeginLoc(memberExpr))
+ << memberExpr->getBase()->getType()->getPointeeType()
<< memberExpr->getSourceRange();
}
@@ -117,9 +121,9 @@ bool RedundantPointerOps::VisitUnaryOperator(UnaryOperator const * unaryOperator
auto innerOp = dyn_cast<UnaryOperator>(subExpr);
if (innerOp && innerOp->getOpcode() == UO_AddrOf)
report(
- DiagnosticsEngine::Warning, "'&' followed by '*', rather use '.'",
+ DiagnosticsEngine::Warning, "'&' followed by '*' operating on %0, rather use '.'",
compat::getBeginLoc(unaryOperator))
- << unaryOperator->getSourceRange();
+ << innerOp->getSubExpr()->getType() << unaryOperator->getSourceRange();
if (auto cxxMemberCallExpr = dyn_cast<CXXMemberCallExpr>(subExpr))
{
auto methodDecl = cxxMemberCallExpr->getMethodDecl();
@@ -128,9 +132,10 @@ bool RedundantPointerOps::VisitUnaryOperator(UnaryOperator const * unaryOperator
auto className = cxxMemberCallExpr->getRecordDecl()->getName();
if (className == "unique_ptr" || className == "shared_ptr" || className == "Reference" || className == "SvRef")
report(
- DiagnosticsEngine::Warning, "'*' followed by '.get()', just use '*'",
+ DiagnosticsEngine::Warning,
+ "'*' followed by '.get()' operating on %0, just use '*'",
compat::getBeginLoc(unaryOperator))
- << unaryOperator->getSourceRange();
+ << compat::getObjectType(cxxMemberCallExpr) << unaryOperator->getSourceRange();
}
}
diff --git a/compilerplugins/clang/test/redundantpointerops.cxx b/compilerplugins/clang/test/redundantpointerops.cxx
index 30c22b02614f..0a1f7b3afad5 100644
--- a/compilerplugins/clang/test/redundantpointerops.cxx
+++ b/compilerplugins/clang/test/redundantpointerops.cxx
@@ -15,7 +15,7 @@ struct Struct1 {
void function1(Struct1& s)
{
- (&s)->x = 1; // expected-error {{'&' followed by '->', rather use '.' [loplugin:redundantpointerops]}}
+ (&s)->x = 1; // expected-error {{'&' followed by '->' operating on 'Struct1', rather use '.' [loplugin:redundantpointerops]}}
};
struct Struct2 {
@@ -25,12 +25,12 @@ struct Struct2 {
void function2(Struct2 s)
{
- (&s)->x = 1; // expected-error {{'&' followed by '->', rather use '.' [loplugin:redundantpointerops]}}
+ (&s)->x = 1; // expected-error {{'&' followed by '->' operating on 'Struct2', rather use '.' [loplugin:redundantpointerops]}}
};
void function3(Struct1& s)
{
- (*(&s)).x = 1; // expected-error {{'&' followed by '*', rather use '.' [loplugin:redundantpointerops]}}
+ (*(&s)).x = 1; // expected-error {{'&' followed by '*' operating on 'Struct1', rather use '.' [loplugin:redundantpointerops]}}
};
//void function4(Struct1* s)
@@ -40,7 +40,7 @@ void function3(Struct1& s)
int function5(std::unique_ptr<int> x)
{
- return *x.get(); // expected-error {{'*' followed by '.get()', just use '*' [loplugin:redundantpointerops]}}
+ return *x.get(); // expected-error-re {{'*' followed by '.get()' operating on '{{.*}}unique_ptr{{.*}}', just use '*' [loplugin:redundantpointerops]}}
};