summaryrefslogtreecommitdiff
path: root/compilerplugins
diff options
context:
space:
mode:
authorNoel Grandin <noel@peralex.com>2016-06-27 08:38:38 +0200
committerNoel Grandin <noel@peralex.com>2016-06-27 08:43:54 +0200
commitf9889a69b9b47cdc19d30cb599667ded03887afe (patch)
tree953a47d746572b4024ece0243c453f8f901af5c6 /compilerplugins
parente4b332358789c0d4df88401021c17e0c88671eb3 (diff)
check for field being returned by non-const ref
Change-Id: I660c98dcbfa6052628ff667886981d075f34b2b7
Diffstat (limited to 'compilerplugins')
-rw-r--r--compilerplugins/clang/singlevalfields.cxx20
1 files changed, 17 insertions, 3 deletions
diff --git a/compilerplugins/clang/singlevalfields.cxx b/compilerplugins/clang/singlevalfields.cxx
index 9fa9293a7b7e..04d1046c46a5 100644
--- a/compilerplugins/clang/singlevalfields.cxx
+++ b/compilerplugins/clang/singlevalfields.cxx
@@ -190,7 +190,8 @@ bool SingleValFields::VisitMemberExpr( const MemberExpr* memberExpr )
if (ignoreLocation(memberExpr) || !isInterestingType(fieldDecl->getType()))
return true;
- const CXXMethodDecl* methodDecl = dyn_cast_or_null<CXXMethodDecl>(get_top_FunctionDecl_from_Stmt(*memberExpr));
+ const FunctionDecl* parentFunctionDecl = get_top_FunctionDecl_from_Stmt(*memberExpr);
+ const CXXMethodDecl* methodDecl = dyn_cast_or_null<CXXMethodDecl>(parentFunctionDecl);
if (methodDecl && (methodDecl->isCopyAssignmentOperator() || methodDecl->isMoveAssignmentOperator()))
return true;
@@ -200,7 +201,20 @@ bool SingleValFields::VisitMemberExpr( const MemberExpr* memberExpr )
bool bPotentiallyAssignedTo = false;
bool bDump = false;
std::string assignValue;
- do {
+
+ // check for field being returned by non-const ref eg. Foo& getFoo() { return f; }
+ if (parent && isa<ReturnStmt>(parent)) {
+ const Stmt* parent2 = parentStmt(parent);
+ if (parent2 && isa<CompoundStmt>(parent2)) {
+ QualType qt = parentFunctionDecl->getReturnType().getDesugaredType(compiler.getASTContext());
+ if (!qt.isConstQualified() && qt->isReferenceType()) {
+ assignValue = "?";
+ bPotentiallyAssignedTo = true;
+ }
+ }
+ }
+
+ while (!bPotentiallyAssignedTo) {
// check for field being accessed by a reference variable e.g. Foo& f = m.foo;
auto parentsList = compiler.getASTContext().getParents(*child);
auto it = parentsList.begin();
@@ -303,7 +317,7 @@ bool SingleValFields::VisitMemberExpr( const MemberExpr* memberExpr )
bDump = true;
break;
}
- } while (true);
+ }
if (bDump)
{
report(