10#include "clang/ASTMatchers/ASTMatchFinder.h"
11#include "clang/ASTMatchers/ASTMatchers.h"
20 hasReturnValue(declRefExpr(
21 to(parmVarDecl(hasType(hasCanonicalType(
22 qualType(lValueReferenceType(pointee(
23 qualType(isConstQualified()))))
27 functionDecl(hasReturnTypeLoc(loc(qualType(
28 hasCanonicalType(equalsBoundNode(
"type"))))))
35 return A.getCanonicalType().withConst() == B.getCanonicalType().withConst();
40 B.getCanonicalType().getNonReferenceType());
44 const ParmVarDecl &PD) {
45 if (FD.getNumParams() != O.getNumParams())
47 for (
unsigned I = 0,
E = FD.getNumParams(); I <
E; ++I) {
48 const ParmVarDecl *DPD = FD.getParamDecl(I);
49 const QualType OPT = O.getParamDecl(I)->getType();
51 if (!llvm::isa<RValueReferenceType>(OPT) ||
63 const ParmVarDecl &PD) {
69 DeclContext::lookup_result LookupResult =
70 FD.getParent()->lookup(FD.getNameInfo().getName());
71 if (LookupResult.isSingleResult()) {
74 for (
const Decl *Overload : LookupResult) {
77 if (
const auto *O = dyn_cast<FunctionDecl>(Overload))
85 const MatchFinder::MatchResult &Result) {
86 const auto *FD = Result.Nodes.getNodeAs<FunctionDecl>(
"func");
87 const auto *PD = Result.Nodes.getNodeAs<ParmVarDecl>(
"param");
88 const auto *R = Result.Nodes.getNodeAs<ReturnStmt>(
"ret");
89 const SourceRange
Range = R->getRetValue()->getSourceRange();
90 if (
Range.isInvalid())
97 "returning a constant reference parameter may cause use-after-free "
98 "when the parameter is constructed from a temporary")
const FunctionDecl * Decl
CharSourceRange Range
SourceRange for the file name.
DiagnosticBuilder diag(SourceLocation Loc, StringRef Description, DiagnosticIDs::Level Level=DiagnosticIDs::Warning)
Add a diagnostic with the check's name.
void check(const ast_matchers::MatchFinder::MatchResult &Result) override
ClangTidyChecks that register ASTMatchers should do the actual work in here.
void registerMatchers(ast_matchers::MatchFinder *Finder) override
Override this to register AST matchers with Finder.
static bool hasSameParameterTypes(const FunctionDecl &FD, const FunctionDecl &O, const ParmVarDecl &PD)
static bool isSameTypeIgnoringConst(QualType A, QualType B)
static const Decl * findRVRefOverload(const FunctionDecl &FD, const ParmVarDecl &PD)
static bool isSameTypeIgnoringConstRef(QualType A, QualType B)