1//===--- MisleadingSetterOfReferenceCheck.cpp - clang-tidy-----------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "MisleadingSetterOfReferenceCheck.h"
10#include "clang/AST/ASTContext.h"
11#include "clang/ASTMatchers/ASTMatchFinder.h"
12
13using namespace clang::ast_matchers;
14
15namespace clang::tidy::bugprone {
16
17void MisleadingSetterOfReferenceCheck::registerMatchers(MatchFinder *Finder) {
18 auto RefField = fieldDecl(hasType(InnerMatcher: hasCanonicalType(InnerMatcher: referenceType(
19 pointee(equalsBoundNode(ID: "type"))))))
20 .bind(ID: "member");
21 auto AssignLHS = memberExpr(
22 hasObjectExpression(InnerMatcher: ignoringParenCasts(InnerMatcher: cxxThisExpr())), member(InnerMatcher: RefField));
23 auto DerefOperand = expr(ignoringParenCasts(
24 InnerMatcher: declRefExpr(to(InnerMatcher: parmVarDecl(equalsBoundNode(ID: "parm"))))));
25 auto AssignRHS = expr(ignoringParenCasts(
26 InnerMatcher: unaryOperator(hasOperatorName(Name: "*"), hasUnaryOperand(InnerMatcher: DerefOperand))));
27
28 auto BinaryOpAssign = binaryOperator(hasOperatorName(Name: "="), hasLHS(InnerMatcher: AssignLHS),
29 hasRHS(InnerMatcher: AssignRHS));
30 auto CXXOperatorCallAssign = cxxOperatorCallExpr(
31 hasOverloadedOperatorName(Name: "="), hasLHS(InnerMatcher: AssignLHS), hasRHS(InnerMatcher: AssignRHS));
32
33 auto SetBody =
34 compoundStmt(statementCountIs(N: 1),
35 anyOf(has(BinaryOpAssign), has(CXXOperatorCallAssign)));
36 auto BadSetFunction =
37 cxxMethodDecl(
38 parameterCountIs(N: 1),
39 hasParameter(
40 N: 0,
41 InnerMatcher: parmVarDecl(hasType(InnerMatcher: hasCanonicalType(InnerMatcher: pointerType(pointee(qualType(
42 hasCanonicalType(InnerMatcher: qualType().bind(ID: "type"))))))))
43 .bind(ID: "parm")),
44 hasBody(InnerMatcher: SetBody))
45 .bind(ID: "bad-set-function");
46 Finder->addMatcher(NodeMatch: BadSetFunction, Action: this);
47}
48
49void MisleadingSetterOfReferenceCheck::check(
50 const MatchFinder::MatchResult &Result) {
51 const auto *Found = Result.Nodes.getNodeAs<CXXMethodDecl>(ID: "bad-set-function");
52 const auto *Member = Result.Nodes.getNodeAs<FieldDecl>(ID: "member");
53
54 diag(Found->getBeginLoc(),
55 "function '%0' can be mistakenly used in order to change the "
56 "reference '%1' instead of the value of it; consider not using a "
57 "pointer as argument")
58 << Found->getName() << Member->getName();
59}
60
61} // namespace clang::tidy::bugprone
62

Provided by KDAB

Privacy Policy
Improve your Profiling and Debugging skills
Find out more

source code of clang-tools-extra/clang-tidy/bugprone/MisleadingSetterOfReferenceCheck.cpp