summaryrefslogtreecommitdiff
path: root/compilerplugins
diff options
context:
space:
mode:
authorNoel <noel.grandin@collabora.co.uk>2021-01-22 13:59:23 +0200
committerNoel Grandin <noel.grandin@collabora.co.uk>2021-01-22 17:46:01 +0100
commit6907cbb8973c9637a07032ad1b885280e91f4d4c (patch)
treedc43ab599b4f9f5c0e6f0fda60639654c5bfd9b2 /compilerplugins
parent9043ab3236e91c9d2e8ecc997e9e46d80547d1bd (diff)
improve loplugin:pointerbool
to look through template instantiations involving std::forward motivated by commit b1617acde182d1683bdfb529794d7456f8b4bf6d drop RadioButton arg defaults the nBits arg in builder.cxx was in the wrong place Change-Id: I222ea2aeea6f44ae54839e824a247a8105392c2d Reviewed-on: https://gerrit.libreoffice.org/c/core/+/109789 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
Diffstat (limited to 'compilerplugins')
-rw-r--r--compilerplugins/clang/pointerbool.cxx37
-rw-r--r--compilerplugins/clang/test/pointerbool.cxx14
2 files changed, 51 insertions, 0 deletions
diff --git a/compilerplugins/clang/pointerbool.cxx b/compilerplugins/clang/pointerbool.cxx
index 66c6a04b3697..6886e1fac63f 100644
--- a/compilerplugins/clang/pointerbool.cxx
+++ b/compilerplugins/clang/pointerbool.cxx
@@ -38,12 +38,42 @@ public:
TraverseDecl(compiler.getASTContext().getTranslationUnitDecl());
}
+ bool shouldVisitTemplateInstantiations() const { return true; }
+
+ bool PreTraverseFunctionDecl(FunctionDecl* decl);
+ bool PostTraverseFunctionDecl(FunctionDecl* decl, bool);
+ bool TraverseFunctionDecl(FunctionDecl* decl);
bool VisitCallExpr(CallExpr const*);
private:
llvm::Optional<APSInt> getCallValue(const Expr* arg);
+ std::vector<FunctionDecl*> functions_;
};
+bool PointerBool::PreTraverseFunctionDecl(FunctionDecl* decl)
+{
+ functions_.push_back(decl);
+ return true;
+}
+
+bool PointerBool::PostTraverseFunctionDecl(FunctionDecl*, bool)
+{
+ assert(!functions_.empty());
+ functions_.pop_back();
+ return true;
+}
+
+bool PointerBool::TraverseFunctionDecl(FunctionDecl* decl)
+{
+ bool ret = true;
+ if (PreTraverseFunctionDecl(decl))
+ {
+ ret = FilteringPlugin::TraverseFunctionDecl(decl);
+ PostTraverseFunctionDecl(decl, ret);
+ }
+ return ret;
+}
+
bool PointerBool::VisitCallExpr(CallExpr const* callExpr)
{
if (ignoreLocation(callExpr))
@@ -98,6 +128,13 @@ bool PointerBool::VisitCallExpr(CallExpr const* callExpr)
<< arg->getSourceRange();
report(DiagnosticsEngine::Note, "method here", param->getLocation())
<< param->getSourceRange();
+ if (!functions_.empty())
+ {
+ auto callerFD = functions_.back();
+ if (callerFD->isTemplateInstantiation())
+ report(DiagnosticsEngine::Note, "instantiated from here",
+ callerFD->getPointOfInstantiation());
+ }
}
return true;
}
diff --git a/compilerplugins/clang/test/pointerbool.cxx b/compilerplugins/clang/test/pointerbool.cxx
index 276a95ae1e00..fcb4a9a31b57 100644
--- a/compilerplugins/clang/test/pointerbool.cxx
+++ b/compilerplugins/clang/test/pointerbool.cxx
@@ -29,4 +29,18 @@ void test1(int* p1)
func_bool(aSeq[0]);
}
+void func_bool2(bool); // expected-note {{method here [loplugin:pointerbool]}}
+
+template <typename... Args> void func_bool_via_forward_template(Args&&... args)
+{
+ // expected-error@+1 {{possibly unwanted implicit conversion when calling bool param [loplugin:pointerbool]}}
+ func_bool2(std::forward<Args>(args)...);
+}
+
+void test2(int p1)
+{
+ // expected-note@+1 {{instantiated from here [loplugin:pointerbool]}}
+ func_bool_via_forward_template(p1);
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */