diff options
author | Noel Grandin <noel@peralex.com> | 2016-06-27 08:38:38 +0200 |
---|---|---|
committer | Noel Grandin <noel@peralex.com> | 2016-06-27 08:43:54 +0200 |
commit | f9889a69b9b47cdc19d30cb599667ded03887afe (patch) | |
tree | 953a47d746572b4024ece0243c453f8f901af5c6 /compilerplugins | |
parent | e4b332358789c0d4df88401021c17e0c88671eb3 (diff) |
check for field being returned by non-const ref
Change-Id: I660c98dcbfa6052628ff667886981d075f34b2b7
Diffstat (limited to 'compilerplugins')
-rw-r--r-- | compilerplugins/clang/singlevalfields.cxx | 20 |
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( |