45 const auto IsSmartptr = hasAnyName(SmartPointers);
47 const auto ResetMethod =
48 cxxMethodDecl(hasName(
"reset"), hasOnlyDefaultParameters());
50 const auto TypeWithReset =
52 anyOf(hasMethod(ResetMethod),
53 isDerivedFrom(cxxRecordDecl(hasMethod(ResetMethod))))),
54 classTemplateSpecializationDecl(
55 hasSpecializedTemplate(classTemplateDecl(has(ResetMethod)))));
57 const auto SmartptrWithReset = expr(hasType(hasUnqualifiedDesugaredType(
58 recordType(hasDeclaration(classTemplateSpecializationDecl(
61 0, templateArgument(refersToType(hasUnqualifiedDesugaredType(
62 recordType(hasDeclaration(TypeWithReset))))))))))));
67 unless(hasAnyArgument(expr(unless(cxxDefaultArgExpr())))),
68 anyOf(on(cxxOperatorCallExpr(hasOverloadedOperatorName(
"->"),
69 hasArgument(0, SmartptrWithReset))
71 on(SmartptrWithReset)))
77 const MatchFinder::MatchResult &Result) {
78 const auto *MemberCall =
79 Result.Nodes.getNodeAs<CXXMemberCallExpr>(
"MemberCall");
82 if (
const auto *Arrow =
83 Result.Nodes.getNodeAs<CXXOperatorCallExpr>(
"ArrowOp")) {
84 const CharSourceRange SmartptrSourceRange =
85 Lexer::getAsCharRange(Arrow->getArg(0)->getSourceRange(),
86 *Result.SourceManager, getLangOpts());
88 diag(MemberCall->getBeginLoc(),
89 "ambiguous call to 'reset()' on a pointee of a smart pointer, prefer "
90 "more explicit approach");
92 diag(MemberCall->getBeginLoc(),
93 "consider dereferencing smart pointer to call 'reset' method "
94 "of the pointee here",
96 << FixItHint::CreateInsertion(SmartptrSourceRange.getBegin(),
"(*")
97 << FixItHint::CreateInsertion(SmartptrSourceRange.getEnd(),
")")
98 << FixItHint::CreateReplacement(
99 CharSourceRange::getCharRange(
100 Arrow->getOperatorLoc(),
101 Arrow->getOperatorLoc().getLocWithOffset(2)),
104 const auto *Member = cast<MemberExpr>(MemberCall->getCallee());
107 diag(MemberCall->getBeginLoc(),
108 "ambiguous call to 'reset()' on a smart pointer with pointee that "
109 "also has a 'reset()' method, prefer more explicit approach");
111 diag(MemberCall->getBeginLoc(),
112 "consider assigning the pointer to 'nullptr' here",
114 << FixItHint::CreateReplacement(
115 SourceRange(Member->getOperatorLoc(), Member->getOperatorLoc()),
117 << FixItHint::CreateReplacement(
118 SourceRange(Member->getMemberLoc(), MemberCall->getEndLoc()),