//===- unittests/StaticAnalyzer/CallDescriptionTest.cpp -------------------===//
//
// 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 "CheckerRegistration.h"
#include "Reusables.h"

#include "clang/AST/ExprCXX.h"
#include "clang/Analysis/PathDiagnostic.h"
#include "clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h"
#include "clang/StaticAnalyzer/Core/Checker.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
#include "clang/StaticAnalyzer/Frontend/AnalysisConsumer.h"
#include "clang/StaticAnalyzer/Frontend/CheckerRegistry.h"
#include "clang/Tooling/Tooling.h"
#include "gtest/gtest.h"
#include <type_traits>

namespace clang {
namespace ento {
namespace {

// A wrapper around CallDescriptionMap<bool> that allows verifying that
// all functions have been found. This is needed because CallDescriptionMap
// isn't supposed to support iteration.
class ResultMap {
  size_t Found, Total;
  CallDescriptionMap<bool> Impl;

public:
  ResultMap(std::initializer_list<std::pair<CallDescription, bool>> Data)
      : Found(0),
        Total(std::count_if(Data.begin(), Data.end(),
                            [](const std::pair<CallDescription, bool> &Pair) {
                              return Pair.second == true;
                            })),
        Impl(std::move(Data)) {}

  const bool *lookup(const CallEvent &Call) {
    const bool *Result = Impl.lookup(Call);
    // If it's a function we expected to find, remember that we've found it.
    if (Result && *Result)
      ++Found;
    return Result;
  }

  // Fail the test if we haven't found all the true-calls we were looking for.
  ~ResultMap() { EXPECT_EQ(Found, Total); }
};

// Scan the code body for call expressions and see if we find all calls that
// we were supposed to find ("true" in the provided ResultMap) and that we
// don't find the ones that we weren't supposed to find
// ("false" in the ResultMap).
template <typename MatchedExprT>
class CallDescriptionConsumer : public ExprEngineConsumer {
  ResultMap &RM;
  void performTest(const Decl *D) {
    using namespace ast_matchers;
    using T = MatchedExprT;

    if (!D->hasBody())
      return;

    const StackFrameContext *SFC =
        Eng.getAnalysisDeclContextManager().getStackFrame(D);
    const ProgramStateRef State = Eng.getInitialState(SFC);

    // FIXME: Maybe use std::variant and std::visit for these.
    const auto MatcherCreator = []() {
      if (std::is_same<T, CallExpr>::value)
        return callExpr();
      if (std::is_same<T, CXXConstructExpr>::value)
        return cxxConstructExpr();
      if (std::is_same<T, CXXMemberCallExpr>::value)
        return cxxMemberCallExpr();
      if (std::is_same<T, CXXOperatorCallExpr>::value)
        return cxxOperatorCallExpr();
      llvm_unreachable("Only these expressions are supported for now.");
    };

    const Expr *E = findNode<T>(D, MatcherCreator());

    CallEventManager &CEMgr = Eng.getStateManager().getCallEventManager();
    CallEventRef<> Call = [=, &CEMgr]() -> CallEventRef<CallEvent> {
      CFGBlock::ConstCFGElementRef ElemRef = {SFC->getCallSiteBlock(),
                                              SFC->getIndex()};
      if (std::is_base_of<CallExpr, T>::value)
        return CEMgr.getCall(E, State, SFC, ElemRef);
      if (std::is_same<T, CXXConstructExpr>::value)
        return CEMgr.getCXXConstructorCall(cast<CXXConstructExpr>(E),
                                           /*Target=*/nullptr, State, SFC,
                                           ElemRef);
      llvm_unreachable("Only these expressions are supported for now.");
    }();

    // If the call actually matched, check if we really expected it to match.
    const bool *LookupResult = RM.lookup(*Call);
    EXPECT_TRUE(!LookupResult || *LookupResult);

    // ResultMap is responsible for making sure that we've found *all* calls.
  }

public:
  CallDescriptionConsumer(CompilerInstance &C,
                          ResultMap &RM)
      : ExprEngineConsumer(C), RM(RM) {}

  bool HandleTopLevelDecl(DeclGroupRef DG) override {
    for (const auto *D : DG)
      performTest(D);
    return true;
  }
};

template <typename MatchedExprT = CallExpr>
class CallDescriptionAction : public ASTFrontendAction {
  ResultMap RM;

public:
  CallDescriptionAction(
      std::initializer_list<std::pair<CallDescription, bool>> Data)
      : RM(Data) {}

  std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &Compiler,
                                                 StringRef File) override {
    return std::make_unique<CallDescriptionConsumer<MatchedExprT>>(Compiler,
                                                                   RM);
  }
};

TEST(CallDescription, SimpleNameMatching) {
  EXPECT_TRUE(tooling::runToolOnCode(
      std::unique_ptr<FrontendAction>(new CallDescriptionAction<>({
          {{{"bar"}}, false}, // false: there's no call to 'bar' in this code.
          {{{"foo"}}, true},  // true: there's a call to 'foo' in this code.
      })),
      "void foo(); void bar() { foo(); }"));
}

TEST(CallDescription, RequiredArguments) {
  EXPECT_TRUE(tooling::runToolOnCode(
      std::unique_ptr<FrontendAction>(new CallDescriptionAction<>({
          {{{"foo"}, 1}, true},
          {{{"foo"}, 2}, false},
      })),
      "void foo(int); void foo(int, int); void bar() { foo(1); }"));
}

TEST(CallDescription, LackOfRequiredArguments) {
  EXPECT_TRUE(tooling::runToolOnCode(
      std::unique_ptr<FrontendAction>(new CallDescriptionAction<>({
          {{{"foo"}, std::nullopt}, true},
          {{{"foo"}, 2}, false},
      })),
      "void foo(int); void foo(int, int); void bar() { foo(1); }"));
}

constexpr StringRef MockStdStringHeader = R"code(
  namespace std { inline namespace __1 {
    template<typename T> class basic_string {
      class Allocator {};
    public:
      basic_string();
      explicit basic_string(const char*, const Allocator & = Allocator());
      ~basic_string();
      T *c_str();
    };
  } // namespace __1
  using string = __1::basic_string<char>;
  } // namespace std
)code";

TEST(CallDescription, QualifiedNames) {
  constexpr StringRef AdditionalCode = R"code(
    void foo() {
      using namespace std;
      basic_string<char> s;
      s.c_str();
    })code";
  const std::string Code = (Twine{MockStdStringHeader} + AdditionalCode).str();
  EXPECT_TRUE(tooling::runToolOnCode(
      std::unique_ptr<FrontendAction>(new CallDescriptionAction<>({
          {{{"std", "basic_string", "c_str"}}, true},
      })),
      Code));
}

TEST(CallDescription, MatchConstructor) {
  constexpr StringRef AdditionalCode = R"code(
    void foo() {
      using namespace std;
      basic_string<char> s("hello");
    })code";
  const std::string Code = (Twine{MockStdStringHeader} + AdditionalCode).str();
  EXPECT_TRUE(tooling::runToolOnCode(
      std::unique_ptr<FrontendAction>(
          new CallDescriptionAction<CXXConstructExpr>({
              {{{"std", "basic_string", "basic_string"}, 2, 2}, true},
          })),
      Code));
}

// FIXME: Test matching destructors: {"std", "basic_string", "~basic_string"}
//        This feature is actually implemented, but the test infra is not yet
//        sophisticated enough for testing this. To do that, we will need to
//        implement a much more advanced dispatching mechanism using the CFG for
//        the implicit destructor events.

TEST(CallDescription, MatchConversionOperator) {
  constexpr StringRef Code = R"code(
    namespace aaa {
    namespace bbb {
    struct Bar {
      operator int();
    };
    } // bbb
    } // aaa
    void foo() {
      aaa::bbb::Bar x;
      int tmp = x;
    })code";
  EXPECT_TRUE(tooling::runToolOnCode(
      std::unique_ptr<FrontendAction>(new CallDescriptionAction<>({
          {{{"aaa", "bbb", "Bar", "operator int"}}, true},
      })),
      Code));
}

TEST(CallDescription, RejectOverQualifiedNames) {
  constexpr auto Code = R"code(
    namespace my {
    namespace std {
      struct container {
        const char *data() const;
      };
    } // namespace std
    } // namespace my

    void foo() {
      using namespace my;
      std::container v;
      v.data();
    })code";

  // FIXME: We should **not** match.
  EXPECT_TRUE(tooling::runToolOnCode(
      std::unique_ptr<FrontendAction>(new CallDescriptionAction<>({
          {{{"std", "container", "data"}}, true},
      })),
      Code));
}

TEST(CallDescription, DontSkipNonInlineNamespaces) {
  constexpr auto Code = R"code(
    namespace my {
    /*not inline*/ namespace v1 {
      void bar();
    } // namespace v1
    } // namespace my
    void foo() {
      my::v1::bar();
    })code";

  {
    SCOPED_TRACE("my v1 bar");
    EXPECT_TRUE(tooling::runToolOnCode(
        std::unique_ptr<FrontendAction>(new CallDescriptionAction<>({
            {{{"my", "v1", "bar"}}, true},
        })),
        Code));
  }
  {
    // FIXME: We should **not** skip non-inline namespaces.
    SCOPED_TRACE("my bar");
    EXPECT_TRUE(tooling::runToolOnCode(
        std::unique_ptr<FrontendAction>(new CallDescriptionAction<>({
            {{{"my", "bar"}}, true},
        })),
        Code));
  }
}

TEST(CallDescription, SkipTopInlineNamespaces) {
  constexpr auto Code = R"code(
    inline namespace my {
    namespace v1 {
      void bar();
    } // namespace v1
    } // namespace my
    void foo() {
      using namespace v1;
      bar();
    })code";

  {
    SCOPED_TRACE("my v1 bar");
    EXPECT_TRUE(tooling::runToolOnCode(
        std::unique_ptr<FrontendAction>(new CallDescriptionAction<>({
            {{{"my", "v1", "bar"}}, true},
        })),
        Code));
  }
  {
    SCOPED_TRACE("v1 bar");
    EXPECT_TRUE(tooling::runToolOnCode(
        std::unique_ptr<FrontendAction>(new CallDescriptionAction<>({
            {{{"v1", "bar"}}, true},
        })),
        Code));
  }
}

TEST(CallDescription, SkipAnonimousNamespaces) {
  constexpr auto Code = R"code(
    namespace {
    namespace std {
    namespace {
    inline namespace {
      struct container {
        const char *data() const { return nullptr; };
      };
    } // namespace inline anonymous
    } // namespace anonymous
    } // namespace std
    } // namespace anonymous

    void foo() {
      std::container v;
      v.data();
    })code";

  EXPECT_TRUE(tooling::runToolOnCode(
      std::unique_ptr<FrontendAction>(new CallDescriptionAction<>({
          {{{"std", "container", "data"}}, true},
      })),
      Code));
}

TEST(CallDescription, AliasNames) {
  constexpr StringRef AliasNamesCode = R"code(
  namespace std {
    struct container {
      const char *data() const;
    };
    using cont = container;
  } // std
)code";

  constexpr StringRef UseAliasInSpelling = R"code(
    void foo() {
      std::cont v;
      v.data();
    })code";
  constexpr StringRef UseStructNameInSpelling = R"code(
    void foo() {
      std::container v;
      v.data();
    })code";
  const std::string UseAliasInSpellingCode =
      (Twine{AliasNamesCode} + UseAliasInSpelling).str();
  const std::string UseStructNameInSpellingCode =
      (Twine{AliasNamesCode} + UseStructNameInSpelling).str();

  // Test if the code spells the alias, wile we match against the struct name,
  // and again matching against the alias.
  {
    SCOPED_TRACE("Using alias in spelling");
    {
      SCOPED_TRACE("std container data");
      EXPECT_TRUE(tooling::runToolOnCode(
          std::unique_ptr<FrontendAction>(new CallDescriptionAction<>({
              {{{"std", "container", "data"}}, true},
          })),
          UseAliasInSpellingCode));
    }
    {
      // FIXME: We should be able to see-through aliases.
      SCOPED_TRACE("std cont data");
      EXPECT_TRUE(tooling::runToolOnCode(
          std::unique_ptr<FrontendAction>(new CallDescriptionAction<>({
              {{{"std", "cont", "data"}}, false},
          })),
          UseAliasInSpellingCode));
    }
  }

  // Test if the code spells the struct name, wile we match against the struct
  // name, and again matching against the alias.
  {
    SCOPED_TRACE("Using struct name in spelling");
    {
      SCOPED_TRACE("std container data");
      EXPECT_TRUE(tooling::runToolOnCode(
          std::unique_ptr<FrontendAction>(new CallDescriptionAction<>({
              {{{"std", "container", "data"}}, true},
          })),
          UseAliasInSpellingCode));
    }
    {
      // FIXME: We should be able to see-through aliases.
      SCOPED_TRACE("std cont data");
      EXPECT_TRUE(tooling::runToolOnCode(
          std::unique_ptr<FrontendAction>(new CallDescriptionAction<>({
              {{{"std", "cont", "data"}}, false},
          })),
          UseAliasInSpellingCode));
    }
  }
}

TEST(CallDescription, AliasSingleNamespace) {
  constexpr StringRef Code = R"code(
    namespace aaa {
    namespace bbb {
    namespace ccc {
      void bar();
    }} // namespace bbb::ccc
    namespace bbb_alias = bbb;
    } // namespace aaa
    void foo() {
      aaa::bbb_alias::ccc::bar();
    })code";
  {
    SCOPED_TRACE("aaa bbb ccc bar");
    EXPECT_TRUE(tooling::runToolOnCode(
        std::unique_ptr<FrontendAction>(new CallDescriptionAction<>({
            {{{"aaa", "bbb", "ccc", "bar"}}, true},
        })),
        Code));
  }
  {
    // FIXME: We should be able to see-through namespace aliases.
    SCOPED_TRACE("aaa bbb_alias ccc bar");
    EXPECT_TRUE(tooling::runToolOnCode(
        std::unique_ptr<FrontendAction>(new CallDescriptionAction<>({
            {{{"aaa", "bbb_alias", "ccc", "bar"}}, false},
        })),
        Code));
  }
}

TEST(CallDescription, AliasMultipleNamespaces) {
  constexpr StringRef Code = R"code(
    namespace aaa {
    namespace bbb {
    namespace ccc {
      void bar();
    }}} // namespace aaa::bbb::ccc
    namespace aaa_bbb_ccc = aaa::bbb::ccc;
    void foo() {
      using namespace aaa_bbb_ccc;
      bar();
    })code";
  {
    SCOPED_TRACE("aaa bbb ccc bar");
    EXPECT_TRUE(tooling::runToolOnCode(
        std::unique_ptr<FrontendAction>(new CallDescriptionAction<>({
            {{{"aaa", "bbb", "ccc", "bar"}}, true},
        })),
        Code));
  }
  {
    // FIXME: We should be able to see-through namespace aliases.
    SCOPED_TRACE("aaa_bbb_ccc bar");
    EXPECT_TRUE(tooling::runToolOnCode(
        std::unique_ptr<FrontendAction>(new CallDescriptionAction<>({
            {{{"aaa_bbb_ccc", "bar"}}, false},
        })),
        Code));
  }
}

TEST(CallDescription, NegativeMatchQualifiedNames) {
  EXPECT_TRUE(tooling::runToolOnCode(
      std::unique_ptr<FrontendAction>(new CallDescriptionAction<>({
          {{{"foo", "bar"}}, false},
          {{{"bar", "foo"}}, false},
          {{{"foo"}}, true},
      })),
      "void foo(); struct bar { void foo(); }; void test() { foo(); }"));
}

TEST(CallDescription, MatchBuiltins) {
  // Test the matching modes CDM::CLibrary and CDM::CLibraryMaybeHardened,
  // which can recognize builtin variants of C library functions.
  {
    SCOPED_TRACE("hardened variants of functions");
    EXPECT_TRUE(tooling::runToolOnCode(
        std::unique_ptr<FrontendAction>(new CallDescriptionAction<>(
            {{{CDM::Unspecified, {"memset"}, 3}, false},
             {{CDM::CLibrary, {"memset"}, 3}, false},
             {{CDM::CLibraryMaybeHardened, {"memset"}, 3}, true}})),
        "void foo() {"
        "  int x;"
        "  __builtin___memset_chk(&x, 0, sizeof(x),"
        "                         __builtin_object_size(&x, 0));"
        "}"));
  }
  {
    SCOPED_TRACE("multiple similar builtins");
    EXPECT_TRUE(tooling::runToolOnCode(
        std::unique_ptr<FrontendAction>(new CallDescriptionAction<>(
            {{{CDM::CLibrary, {"memcpy"}, 3}, false},
             {{CDM::CLibrary, {"wmemcpy"}, 3}, true}})),
        R"(void foo(wchar_t *x, wchar_t *y) {
            __builtin_wmemcpy(x, y, sizeof(wchar_t));
          })"));
  }
  {
    SCOPED_TRACE("multiple similar builtins reversed order");
    EXPECT_TRUE(tooling::runToolOnCode(
        std::unique_ptr<FrontendAction>(new CallDescriptionAction<>(
            {{{CDM::CLibrary, {"wmemcpy"}, 3}, true},
             {{CDM::CLibrary, {"memcpy"}, 3}, false}})),
        R"(void foo(wchar_t *x, wchar_t *y) {
            __builtin_wmemcpy(x, y, sizeof(wchar_t));
          })"));
  }
  {
    SCOPED_TRACE("multiple similar builtins with hardened variant");
    EXPECT_TRUE(tooling::runToolOnCode(
        std::unique_ptr<FrontendAction>(new CallDescriptionAction<>(
            {{{CDM::CLibraryMaybeHardened, {"memcpy"}, 3}, false},
             {{CDM::CLibraryMaybeHardened, {"wmemcpy"}, 3}, true}})),
        R"(typedef __typeof(sizeof(int)) size_t;
          extern wchar_t *__wmemcpy_chk (wchar_t *__restrict __s1,
                                          const wchar_t *__restrict __s2,
                                          size_t __n, size_t __ns1);
          void foo(wchar_t *x, wchar_t *y) {
            __wmemcpy_chk(x, y, sizeof(wchar_t), 1234);
          })"));
  }
  {
    SCOPED_TRACE(
        "multiple similar builtins with hardened variant reversed order");
    EXPECT_TRUE(tooling::runToolOnCode(
        std::unique_ptr<FrontendAction>(new CallDescriptionAction<>(
            {{{CDM::CLibraryMaybeHardened, {"wmemcpy"}, 3}, true},
             {{CDM::CLibraryMaybeHardened, {"memcpy"}, 3}, false}})),
        R"(typedef __typeof(sizeof(int)) size_t;
          extern wchar_t *__wmemcpy_chk (wchar_t *__restrict __s1,
                                          const wchar_t *__restrict __s2,
                                          size_t __n, size_t __ns1);
          void foo(wchar_t *x, wchar_t *y) {
            __wmemcpy_chk(x, y, sizeof(wchar_t), 1234);
          })"));
  }
  {
    SCOPED_TRACE("lookbehind and lookahead mismatches");
    EXPECT_TRUE(tooling::runToolOnCode(
        std::unique_ptr<FrontendAction>(
            new CallDescriptionAction<>({{{CDM::CLibrary, {"func"}}, false}})),
        R"(
          void funcXXX();
          void XXXfunc();
          void XXXfuncXXX();
          void test() {
            funcXXX();
            XXXfunc();
            XXXfuncXXX();
          })"));
  }
  {
    SCOPED_TRACE("lookbehind and lookahead matches");
    EXPECT_TRUE(tooling::runToolOnCode(
        std::unique_ptr<FrontendAction>(
            new CallDescriptionAction<>({{{CDM::CLibrary, {"func"}}, true}})),
        R"(
          void func();
          void func_XXX();
          void XXX_func();
          void XXX_func_XXX();

          void test() {
            func(); // exact match
            func_XXX();
            XXX_func();
            XXX_func_XXX();
          })"));
  }
}

//===----------------------------------------------------------------------===//
// Testing through a checker interface.
//
// Above, the static analyzer isn't run properly, only the bare minimum to
// create CallEvents. This causes CallEvents through function pointers to not
// refer to the pointee function, but this works fine if we run
// AnalysisASTConsumer.
//===----------------------------------------------------------------------===//

class CallDescChecker
    : public Checker<check::PreCall, check::PreStmt<CallExpr>> {
  CallDescriptionSet Set = {{{"bar"}, 0}};

public:
  void checkPreCall(const CallEvent &Call, CheckerContext &C) const {
    if (Set.contains(Call)) {
      C.getBugReporter().EmitBasicReport(
          Call.getDecl(), this, "CallEvent match", categories::LogicError,
          "CallEvent match",
          PathDiagnosticLocation{Call.getDecl(), C.getSourceManager()});
    }
  }

  void checkPreStmt(const CallExpr *CE, CheckerContext &C) const {
    if (Set.containsAsWritten(*CE)) {
      C.getBugReporter().EmitBasicReport(
          CE->getCalleeDecl(), this, "CallExpr match", categories::LogicError,
          "CallExpr match",
          PathDiagnosticLocation{CE->getCalleeDecl(), C.getSourceManager()});
    }
  }
};

void addCallDescChecker(AnalysisASTConsumer &AnalysisConsumer,
                        AnalyzerOptions &AnOpts) {
  AnOpts.CheckersAndPackages = {{"test.CallDescChecker", true}};
  AnalysisConsumer.AddCheckerRegistrationFn([](CheckerRegistry &Registry) {
    Registry.addChecker<CallDescChecker>("test.CallDescChecker", "Description",
                                         "");
  });
}

TEST(CallDescription, CheckCallExprMatching) {
  // Imprecise matching shouldn't catch the call to bar, because its obscured
  // by a function pointer.
  constexpr StringRef FnPtrCode = R"code(
    void bar();
    void foo() {
      void (*fnptr)() = bar;
      fnptr();
    })code";
  std::string Diags;
  EXPECT_TRUE(runCheckerOnCode<addCallDescChecker>(FnPtrCode.str(), Diags,
                                                   /*OnlyEmitWarnings*/ true));
  EXPECT_EQ("test.CallDescChecker: CallEvent match\n", Diags);

  // This should be caught properly by imprecise matching, as the call is done
  // purely through syntactic means.
  constexpr StringRef Code = R"code(
    void bar();
    void foo() {
      bar();
    })code";
  Diags.clear();
  EXPECT_TRUE(runCheckerOnCode<addCallDescChecker>(Code.str(), Diags,
                                                   /*OnlyEmitWarnings*/ true));
  EXPECT_EQ("test.CallDescChecker: CallEvent match\n"
            "test.CallDescChecker: CallExpr match\n",
            Diags);
}

} // namespace
} // namespace ento
} // namespace clang
