summaryrefslogtreecommitdiff
path: root/compilerplugins/clang/passstuffbyref.cxx
diff options
context:
space:
mode:
authorStephan Bergmann <sbergman@redhat.com>2016-06-08 17:14:34 +0200
committerStephan Bergmann <sbergman@redhat.com>2016-06-08 17:14:34 +0200
commit4d49c9601c9b3e26a336e08e057d299895683480 (patch)
tree469e3c18c2167db45cffec0a21a99abda8406c54 /compilerplugins/clang/passstuffbyref.cxx
parent46c7ecf760bbea6541507c319e8e722f9b4ec712 (diff)
Let loplugin:passstuffbyref also look at fn defn not preceded by any decl
Change-Id: I752bc96d2d521d790e919283cabb14b6526626f4
Diffstat (limited to 'compilerplugins/clang/passstuffbyref.cxx')
-rw-r--r--compilerplugins/clang/passstuffbyref.cxx21
1 files changed, 15 insertions, 6 deletions
diff --git a/compilerplugins/clang/passstuffbyref.cxx b/compilerplugins/clang/passstuffbyref.cxx
index a14d01f6a5a4..ca2283cbb5e0 100644
--- a/compilerplugins/clang/passstuffbyref.cxx
+++ b/compilerplugins/clang/passstuffbyref.cxx
@@ -58,8 +58,11 @@ bool PassStuffByRef::VisitFunctionDecl(const FunctionDecl * functionDecl) {
if (ignoreLocation(functionDecl)) {
return true;
}
- if (functionDecl->isDeleted())
+ if (functionDecl->isDeleted()
+ || functionDecl->isFunctionTemplateSpecialization())
+ {
return true;
+ }
// only consider base declarations, not overriden ones, or we warn on methods that
// are overriding stuff from external libraries
const CXXMethodDecl * methodDecl = dyn_cast<CXXMethodDecl>(functionDecl);
@@ -73,9 +76,8 @@ bool PassStuffByRef::VisitFunctionDecl(const FunctionDecl * functionDecl) {
}
void PassStuffByRef::checkParams(const FunctionDecl * functionDecl) {
- // only warn on the definition/prototype of the function,
- // not on the function implementation
- if (functionDecl->isThisDeclarationADefinition()) {
+ // Only warn on the definition of the function:
+ if (!functionDecl->isThisDeclarationADefinition()) {
return;
}
unsigned n = functionDecl->getNumParams();
@@ -109,6 +111,13 @@ void PassStuffByRef::checkParams(const FunctionDecl * functionDecl) {
("passing primitive type param %0 by const &, rather pass by value"),
pvDecl->getLocation())
<< t << pvDecl->getSourceRange();
+ auto can = functionDecl->getCanonicalDecl();
+ if (can->getLocation() != functionDecl->getLocation()) {
+ report(
+ DiagnosticsEngine::Note, "function is declared here:",
+ can->getLocation())
+ << can->getSourceRange();
+ }
}
}
}
@@ -223,10 +232,10 @@ bool PassStuffByRef::isPrimitiveConstRef(QualType type) {
if (type->isIncompleteType()) {
return false;
}
- if (!type->isReferenceType()) {
+ const clang::ReferenceType* referenceType = type->getAs<ReferenceType>();
+ if (referenceType == nullptr) {
return false;
}
- const clang::ReferenceType* referenceType = dyn_cast<ReferenceType>(type);
QualType pointeeQT = referenceType->getPointeeType();
if (!pointeeQT.isConstQualified()) {
return false;