//===--- UnhandledSelfAssignmentCheck.cpp - clang-tidy --------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "UnhandledSelfAssignmentCheck.h"
#include "clang/AST/ASTContext.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"

using namespace clang::ast_matchers;

namespace clang {
namespace tidy {
namespace bugprone {

UnhandledSelfAssignmentCheck::UnhandledSelfAssignmentCheck(
    StringRef Name, ClangTidyContext *Context)
    : ClangTidyCheck(Name, Context),
      WarnOnlyIfThisHasSuspiciousField(
          Options.get("WarnOnlyIfThisHasSuspiciousField", true)) {}

void UnhandledSelfAssignmentCheck::storeOptions(
    ClangTidyOptions::OptionMap &Opts) {
  Options.store(Opts, "WarnOnlyIfThisHasSuspiciousField",
                WarnOnlyIfThisHasSuspiciousField);
}

void UnhandledSelfAssignmentCheck::registerMatchers(MatchFinder *Finder) {
  if (!getLangOpts().CPlusPlus)
    return;

  // We don't care about deleted, default or implicit operator implementations.
  const auto IsUserDefined = cxxMethodDecl(
      isDefinition(), unless(anyOf(isDeleted(), isImplicit(), isDefaulted())));

  // We don't need to worry when a copy assignment operator gets the other
  // object by value.
  const auto HasReferenceParam =
      cxxMethodDecl(hasParameter(0, parmVarDecl(hasType(referenceType()))));

  // Self-check: Code compares something with 'this' pointer. We don't check
  // whether it is actually the parameter what we compare.
  const auto HasNoSelfCheck = cxxMethodDecl(unless(hasDescendant(
      binaryOperator(anyOf(hasOperatorName("=="), hasOperatorName("!=")),
                     has(ignoringParenCasts(cxxThisExpr()))))));

  // Both copy-and-swap and copy-and-move method creates a copy first and
  // assign it to 'this' with swap or move.
  // In the non-template case, we can search for the copy constructor call.
  const auto HasNonTemplateSelfCopy = cxxMethodDecl(
      ofClass(cxxRecordDecl(unless(hasAncestor(classTemplateDecl())))),
      hasDescendant(cxxConstructExpr(hasDeclaration(cxxConstructorDecl(
          isCopyConstructor(), ofClass(equalsBoundNode("class")))))));

  // In the template case, we need to handle two separate cases: 1) a local
  // variable is created with the copy, 2) copy is created only as a temporary
  // object.
  const auto HasTemplateSelfCopy = cxxMethodDecl(
      ofClass(cxxRecordDecl(hasAncestor(classTemplateDecl()))),
      anyOf(hasDescendant(
                varDecl(hasType(cxxRecordDecl(equalsBoundNode("class"))),
                        hasDescendant(parenListExpr()))),
            hasDescendant(cxxUnresolvedConstructExpr(hasDescendant(declRefExpr(
                hasType(cxxRecordDecl(equalsBoundNode("class")))))))));

  // If inside the copy assignment operator another assignment operator is
  // called on 'this' we assume that self-check might be handled inside
  // this nested operator.
  const auto HasNoNestedSelfAssign =
      cxxMethodDecl(unless(hasDescendant(cxxMemberCallExpr(callee(cxxMethodDecl(
          hasName("operator="), ofClass(equalsBoundNode("class"))))))));

  DeclarationMatcher AdditionalMatcher = cxxMethodDecl();
  if (WarnOnlyIfThisHasSuspiciousField) {
    // Matcher for standard smart pointers.
    const auto SmartPointerType = qualType(hasUnqualifiedDesugaredType(
        recordType(hasDeclaration(classTemplateSpecializationDecl(
            hasAnyName("::std::shared_ptr", "::std::unique_ptr",
                       "::std::weak_ptr", "::std::auto_ptr"),
            templateArgumentCountIs(1))))));

    // We will warn only if the class has a pointer or a C array field which
    // probably causes a problem during self-assignment (e.g. first resetting
    // the pointer member, then trying to access the object pointed by the
    // pointer, or memcpy overlapping arrays).
    AdditionalMatcher = cxxMethodDecl(ofClass(cxxRecordDecl(
        has(fieldDecl(anyOf(hasType(pointerType()), hasType(SmartPointerType),
                            hasType(arrayType())))))));
  }

  Finder->addMatcher(cxxMethodDecl(ofClass(cxxRecordDecl().bind("class")),
                                   isCopyAssignmentOperator(), IsUserDefined,
                                   HasReferenceParam, HasNoSelfCheck,
                                   unless(HasNonTemplateSelfCopy),
                                   unless(HasTemplateSelfCopy),
                                   HasNoNestedSelfAssign, AdditionalMatcher)
                         .bind("copyAssignmentOperator"),
                     this);
}

void UnhandledSelfAssignmentCheck::check(
    const MatchFinder::MatchResult &Result) {
  const auto *MatchedDecl =
      Result.Nodes.getNodeAs<CXXMethodDecl>("copyAssignmentOperator");
  diag(MatchedDecl->getLocation(),
       "operator=() does not handle self-assignment properly");
}

} // namespace bugprone
} // namespace tidy
} // namespace clang
